Feature Tip: Add private address tag to any address under My Name Tag !
Source Code
Latest 25 from a total of 33 transactions
| Transaction Hash |
Method
|
Block
|
From
|
|
To
|
||||
|---|---|---|---|---|---|---|---|---|---|
| Execute Buyback | 24133916 | 43 hrs ago | IN | 0 ETH | 0.00029939 | ||||
| Configure Snowba... | 24130276 | 2 days ago | IN | 0 ETH | 0.00000102 | ||||
| Execute Buyback | 24127583 | 2 days ago | IN | 0 ETH | 0.00030121 | ||||
| Execute Buyback | 24122947 | 3 days ago | IN | 0 ETH | 0.00030023 | ||||
| Execute Buyback | 24122368 | 3 days ago | IN | 0 ETH | 0.00030074 | ||||
| Execute Buyback | 24120448 | 3 days ago | IN | 0 ETH | 0.00030129 | ||||
| Execute Buyback | 24118460 | 3 days ago | IN | 0 ETH | 0.00030122 | ||||
| Execute Buyback | 24117941 | 4 days ago | IN | 0 ETH | 0.00030096 | ||||
| Execute Buyback | 24117868 | 4 days ago | IN | 0 ETH | 0.00029939 | ||||
| Execute Buyback | 24117412 | 4 days ago | IN | 0 ETH | 0.00008762 | ||||
| Execute Buyback | 24115917 | 4 days ago | IN | 0 ETH | 0.00029939 | ||||
| Execute Buyback | 24114816 | 4 days ago | IN | 0 ETH | 0.00030133 | ||||
| Execute Buyback | 24114717 | 4 days ago | IN | 0 ETH | 0.00030128 | ||||
| Execute Buyback | 24114554 | 4 days ago | IN | 0 ETH | 0.00030122 | ||||
| Execute Buyback | 24114220 | 4 days ago | IN | 0 ETH | 0.00030034 | ||||
| Execute Buyback | 24114149 | 4 days ago | IN | 0 ETH | 0.00029995 | ||||
| Execute Buyback | 24111842 | 4 days ago | IN | 0 ETH | 0.00030116 | ||||
| Configure Snowba... | 24108646 | 5 days ago | IN | 0 ETH | 0.00000105 | ||||
| Execute Buyback | 24108301 | 5 days ago | IN | 0 ETH | 0.00029937 | ||||
| Execute Buyback | 24108206 | 5 days ago | IN | 0 ETH | 0.00030012 | ||||
| Execute Buyback | 24107015 | 5 days ago | IN | 0 ETH | 0.00030035 | ||||
| Execute Buyback | 24098461 | 6 days ago | IN | 0 ETH | 0.00030049 | ||||
| Execute Buyback | 24096794 | 6 days ago | IN | 0 ETH | 0.00029991 | ||||
| Execute Buyback | 24096432 | 7 days ago | IN | 0 ETH | 0.00029989 | ||||
| Set Platform Fee... | 24096158 | 7 days ago | IN | 0 ETH | 0.00000288 |
Latest 1 internal transaction
Advanced mode:
| Parent Transaction Hash | Method | Block |
From
|
|
To
|
||
|---|---|---|---|---|---|---|---|
| 0x60c03462 | 24094015 | 7 days ago | Contract Creation | 0 ETH |
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
SnowballHookV2
Compiler Version
v0.8.24+commit.e11b9ed9
Optimization Enabled:
Yes with 100 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "../interfaces/IPoolManager.sol";
import "../interfaces/IHooks.sol";
import "../interfaces/ICurrency.sol";
import "../interfaces/IUnlockCallback.sol";
/**
* @title SnowballHookV2
* @notice Uniswap V4 hook with buy/sell taxes, buyback/burn, and platform fees
*
* Tax Collection Strategy:
* - For BUYS (WETH → Token): Take WETH fee during beforeSwap
* - For SELLS (Token → WETH): Track WETH fee during afterSwap
*
* Fee Distribution on Buyback:
* - 20% of collected fees → Platform fee collector (in WETH) [default, adjustable by controller]
* - 80% of collected fees → Buyback and burn tokens
*
* Tax Limits:
* - Max buy tax: 15% (1500 bps)
* - Max sell tax: 15% (1500 bps)
* - Platform fee: 0-50% of collected tax (adjustable by controller only)
*
* Required hook flags: 0x00CC
* - beforeSwap = 0x0080 (bit 7)
* - afterSwap = 0x0040 (bit 6)
* - beforeSwapReturnDelta = 0x0008 (bit 3)
* - afterSwapReturnDelta = 0x0004 (bit 2)
*
* TAX APPROACH:
* - BUY: Take WETH fee in beforeSwap (from input)
* - SELL: Take WETH fee in afterSwap (from output) - user receives WETH minus tax
*/
contract SnowballHookV2 is IHooks, IUnlockCallback {
using SafeERC20 for IERC20;
using CurrencyLibrary for Currency;
// ============================================================
// CONSTANTS
// ============================================================
uint256 public constant FEE_DENOMINATOR = 10000;
uint256 public constant MAX_TAX_BPS = 1500; // Max 15% buy/sell tax
uint256 public constant MAX_PLATFORM_FEE_BPS = 5000; // Max 50% of fees to platform
// ============================================================
// STATE
// ============================================================
address public immutable poolManager;
address public immutable weth;
address public controller;
address public platformFeeCollector;
address public factory; // Factory can auto-configure snowball for new tokens
uint256 public platformFeeBps; // Platform's share of collected fees (default 10%)
struct TaxConfig {
uint16 buyTaxBps; // Tax on buys (0-15%)
uint16 sellTaxBps; // Tax on sells (0-15%)
uint256 threshold; // WETH threshold for buyback
uint256 accumulated; // WETH accumulated (total)
address tokenAddress; // Token being traded
bool enabled;
}
mapping(bytes32 => TaxConfig) public taxConfigs;
uint256 public totalBuybacks;
uint256 public totalBurned;
uint256 public totalPlatformFees; // Total WETH sent to platform
// Track pending sell tax to apply in afterSwap (legacy, now unused)
mapping(bytes32 => uint256) private pendingSellTax;
// Track accumulated token fees from sells (to be converted to WETH during buyback)
mapping(bytes32 => uint256) public tokenFeesAccumulated;
// ============================================================
// EVENTS
// ============================================================
event TaxTaken(bytes32 indexed poolId, uint256 amount, bool isBuy);
event BuybackExecuted(bytes32 indexed poolId, uint256 wethSpent, uint256 tokensBurned);
event PlatformFeeSent(bytes32 indexed poolId, uint256 wethAmount, address recipient);
event TokensConvertedToWeth(bytes32 indexed poolId, uint256 tokensSpent, uint256 wethReceived);
event ThresholdReached(bytes32 indexed poolId, uint256 accumulated);
event PlatformFeeCollectorUpdated(address oldCollector, address newCollector);
event PlatformFeeBpsUpdated(uint256 oldBps, uint256 newBps);
// ============================================================
// ERRORS
// ============================================================
error NotPoolManager();
error NotController();
error InvalidTax();
error InvalidThreshold();
error InvalidAddress();
error InvalidPlatformFee();
// ============================================================
// CONSTRUCTOR
// ============================================================
constructor(address _poolManager, address _weth, address _controller, address _platformFeeCollector) {
poolManager = _poolManager;
weth = _weth;
controller = _controller;
platformFeeCollector = _platformFeeCollector;
platformFeeBps = 2000; // Default 20% of fees to platform
}
// ============================================================
// ADMIN FUNCTIONS
// ============================================================
function configureSnowball(
bytes32 poolId,
address tokenAddress,
uint16 buyTaxBps,
uint16 sellTaxBps,
uint256 threshold
) external {
// Allow both controller and factory to configure
if (msg.sender != controller && msg.sender != factory) revert NotController();
if (buyTaxBps > MAX_TAX_BPS) revert InvalidTax();
if (sellTaxBps > MAX_TAX_BPS) revert InvalidTax();
if (threshold == 0) revert InvalidThreshold();
taxConfigs[poolId] = TaxConfig({
buyTaxBps: buyTaxBps,
sellTaxBps: sellTaxBps,
threshold: threshold,
accumulated: taxConfigs[poolId].accumulated,
tokenAddress: tokenAddress,
enabled: true
});
}
function updateTaxRates(bytes32 poolId, uint16 buyTaxBps, uint16 sellTaxBps) external {
if (msg.sender != controller) revert NotController();
if (buyTaxBps > MAX_TAX_BPS) revert InvalidTax();
if (sellTaxBps > MAX_TAX_BPS) revert InvalidTax();
taxConfigs[poolId].buyTaxBps = buyTaxBps;
taxConfigs[poolId].sellTaxBps = sellTaxBps;
}
function setEnabled(bytes32 poolId, bool enabled) external {
if (msg.sender != controller) revert NotController();
taxConfigs[poolId].enabled = enabled;
}
function setController(address newController) external {
if (msg.sender != controller) revert NotController();
if (newController == address(0)) revert InvalidAddress();
controller = newController;
}
function setFactory(address newFactory) external {
if (msg.sender != controller) revert NotController();
factory = newFactory;
}
function setPlatformFeeCollector(address newCollector) external {
if (msg.sender != controller) revert NotController();
if (newCollector == address(0)) revert InvalidAddress();
address oldCollector = platformFeeCollector;
platformFeeCollector = newCollector;
emit PlatformFeeCollectorUpdated(oldCollector, newCollector);
}
/**
* @notice Update the platform fee percentage
* @param newPlatformFeeBps New platform fee in basis points (0-5000, i.e., 0-50%)
* @dev Only callable by controller. Max 50% to ensure buyback always has funds.
*/
function setPlatformFeeBps(uint256 newPlatformFeeBps) external {
if (msg.sender != controller) revert NotController();
if (newPlatformFeeBps > MAX_PLATFORM_FEE_BPS) revert InvalidPlatformFee();
uint256 oldBps = platformFeeBps;
platformFeeBps = newPlatformFeeBps;
emit PlatformFeeBpsUpdated(oldBps, newPlatformFeeBps);
}
// ============================================================
// HOOK PERMISSIONS - Must match address flags 0x00C8
// ============================================================
function getHookPermissions() external pure returns (Hooks.Permissions memory) {
return Hooks.Permissions({
beforeInitialize: false,
afterInitialize: false,
beforeAddLiquidity: false,
afterAddLiquidity: false,
beforeRemoveLiquidity: false,
afterRemoveLiquidity: false,
beforeSwap: true, // Take WETH fee on buys
afterSwap: true, // Track WETH fee on sells
beforeDonate: false,
afterDonate: false,
beforeSwapReturnDelta: true, // Return delta for buy fee
afterSwapReturnDelta: true, // Return delta for sell fee (take WETH from output)
afterAddLiquidityReturnDelta: false,
afterRemoveLiquidityReturnDelta: false
});
}
// ============================================================
// HOOK CALLBACKS
// ============================================================
function beforeInitialize(address, PoolKey calldata, uint160) external pure returns (bytes4) {
return IHooks.beforeInitialize.selector;
}
function afterInitialize(address, PoolKey calldata, uint160, int24) external pure returns (bytes4) {
return IHooks.afterInitialize.selector;
}
function beforeAddLiquidity(address, PoolKey calldata, ModifyLiquidityParams calldata, bytes calldata)
external pure returns (bytes4)
{
return IHooks.beforeAddLiquidity.selector;
}
function afterAddLiquidity(address, PoolKey calldata, ModifyLiquidityParams calldata, BalanceDelta, BalanceDelta, bytes calldata)
external pure returns (bytes4, BalanceDelta)
{
return (IHooks.afterAddLiquidity.selector, BalanceDelta.wrap(0));
}
function beforeRemoveLiquidity(address, PoolKey calldata, ModifyLiquidityParams calldata, bytes calldata)
external pure returns (bytes4)
{
return IHooks.beforeRemoveLiquidity.selector;
}
function afterRemoveLiquidity(address, PoolKey calldata, ModifyLiquidityParams calldata, BalanceDelta, BalanceDelta, bytes calldata)
external pure returns (bytes4, BalanceDelta)
{
return (IHooks.afterRemoveLiquidity.selector, BalanceDelta.wrap(0));
}
/**
* @notice Called BEFORE each swap - take fee on BOTH buys and sells
*
* For buys (WETH → Token): Take WETH fee from input
* For sells (Token → WETH): Take token fee from input, store for later WETH conversion
*/
function beforeSwap(
address,
PoolKey calldata key,
SwapParams calldata params,
bytes calldata
) external returns (bytes4, BeforeSwapDelta, uint24) {
if (msg.sender != poolManager) revert NotPoolManager();
bytes32 poolId = _getPoolId(key);
TaxConfig storage config = taxConfigs[poolId];
if (!config.enabled) {
return (IHooks.beforeSwap.selector, BeforeSwapDelta.wrap(0), 0);
}
// Determine trade direction
address currency1Addr = Currency.unwrap(key.currency1);
bool wethIsCurrency1 = currency1Addr == weth;
// Determine if this is a buy or sell
bool isBuy;
if (wethIsCurrency1) {
isBuy = !params.zeroForOne;
} else {
isBuy = params.zeroForOne;
}
if (isBuy) {
// BUY: WETH → Token - Take WETH fee now
uint16 taxBps = config.buyTaxBps;
if (taxBps == 0) {
return (IHooks.beforeSwap.selector, BeforeSwapDelta.wrap(0), 0);
}
// Get WETH amount being spent
uint256 wethAmount;
if (params.amountSpecified < 0) {
wethAmount = uint256(uint128(-int128(params.amountSpecified)));
} else {
wethAmount = uint256(uint128(int128(params.amountSpecified)));
}
uint256 feeAmount = (wethAmount * taxBps) / FEE_DENOMINATOR;
if (feeAmount > 0) {
Currency wethCurrency = wethIsCurrency1 ? key.currency1 : key.currency0;
// Take WETH to this contract
IPoolManager(poolManager).take(wethCurrency, address(this), feeAmount);
config.accumulated += feeAmount;
emit TaxTaken(poolId, feeAmount, true);
// Return delta: caller pays more
bool exactInput = params.amountSpecified < 0;
int128 specifiedDelta = exactInput ? int128(uint128(feeAmount)) : int128(0);
int128 unspecifiedDelta = exactInput ? int128(0) : int128(uint128(feeAmount));
BeforeSwapDelta hookDelta = BeforeSwapDelta.wrap(
int256(int128(specifiedDelta)) << 128 | int256(int128(unspecifiedDelta))
);
return (IHooks.beforeSwap.selector, hookDelta, 0);
}
}
// SELL: Handled in afterSwap - we take WETH from the output
return (IHooks.beforeSwap.selector, BeforeSwapDelta.wrap(0), 0);
}
/**
* @notice Called AFTER each swap - collect sell tax from WETH output
*
* For sells (Token → WETH):
* - Calculate the WETH the user would receive
* - Take X% as tax (collected as WETH)
* - Return positive delta to reduce user's WETH output
*/
function afterSwap(
address,
PoolKey calldata key,
SwapParams calldata params,
BalanceDelta delta,
bytes calldata
) external returns (bytes4, int128) {
if (msg.sender != poolManager) revert NotPoolManager();
bytes32 poolId = _getPoolId(key);
TaxConfig storage config = taxConfigs[poolId];
if (!config.enabled) {
return (IHooks.afterSwap.selector, 0);
}
// Determine trade direction
address currency1Addr = Currency.unwrap(key.currency1);
bool wethIsCurrency1 = currency1Addr == weth;
// Determine if this is a sell (Token → WETH)
bool isSell;
if (wethIsCurrency1) {
isSell = params.zeroForOne; // Selling token0 for token1 (WETH)
} else {
isSell = !params.zeroForOne; // Selling token1 for token0 (WETH)
}
int128 hookDelta = 0;
if (isSell && config.sellTaxBps > 0) {
// Calculate WETH output from the swap
// delta represents changes from the swap caller's (swapper's) perspective
// For a sell, they receive WETH so WETH delta should be positive for them
int128 amount0 = int128(int256(BalanceDelta.unwrap(delta)) >> 128);
int128 amount1 = int128(int256(BalanceDelta.unwrap(delta)));
// WETH delta: positive means swapper receives WETH
int128 wethDelta = wethIsCurrency1 ? amount1 : amount0;
// Check both positive and negative - try to understand the actual output
uint256 wethOutput;
if (wethDelta > 0) {
// Positive: swapper is receiving WETH
wethOutput = uint256(uint128(wethDelta));
} else if (wethDelta < 0) {
// Negative: this shouldn't happen for a sell, but handle it
wethOutput = uint256(uint128(-wethDelta));
} else {
wethOutput = 0;
}
if (wethOutput > 0) {
uint256 feeAmount = (wethOutput * config.sellTaxBps) / FEE_DENOMINATOR;
if (feeAmount > 0) {
// Take WETH to this contract
Currency wethCurrency = wethIsCurrency1 ? key.currency1 : key.currency0;
IPoolManager(poolManager).take(wethCurrency, address(this), feeAmount);
// Add to accumulated WETH (same as buy tax)
config.accumulated += feeAmount;
emit TaxTaken(poolId, feeAmount, false);
// Return positive delta = user receives less WETH (reduces their output)
hookDelta = int128(uint128(feeAmount));
}
}
}
// Check threshold for buyback
if (config.accumulated >= config.threshold) {
emit ThresholdReached(poolId, config.accumulated);
}
return (IHooks.afterSwap.selector, hookDelta);
}
function beforeDonate(address, PoolKey calldata, uint256, uint256, bytes calldata)
external pure returns (bytes4)
{
return IHooks.beforeDonate.selector;
}
function afterDonate(address, PoolKey calldata, uint256, uint256, bytes calldata)
external pure returns (bytes4)
{
return IHooks.afterDonate.selector;
}
// ============================================================
// BUYBACK FUNCTIONS
// ============================================================
/**
* @notice Execute buyback and burn, sending platform fee first
* @dev Can be called by anyone when threshold is met
*
* Flow:
* 1. First convert any accumulated tokens (from sells) to WETH
* 2. Calculate platform fee from total WETH
* 3. Send platform fee to collector
* 4. Use remaining WETH to buyback tokens
* 5. Burn the purchased tokens
*/
function executeBuyback(PoolKey calldata key) external {
bytes32 poolId = _getPoolId(key);
TaxConfig storage config = taxConfigs[poolId];
require(config.enabled, "Not enabled");
// All taxes (buy and sell) are now collected as WETH directly
// Check threshold on WETH accumulated
require(config.accumulated >= config.threshold, "Threshold not reached");
// Get actual WETH balance in this contract
uint256 wethBalance = IERC20(weth).balanceOf(address(this));
require(wethBalance > 0, "No WETH to buyback");
uint256 totalAmount = wethBalance < config.accumulated ? wethBalance : config.accumulated;
config.accumulated = config.accumulated > totalAmount ? config.accumulated - totalAmount : 0;
// Calculate platform fee (adjustable, default 20% of total)
uint256 platformFee = (totalAmount * platformFeeBps) / FEE_DENOMINATOR;
uint256 buybackAmount = totalAmount - platformFee;
// Send platform fee to collector
if (platformFee > 0 && platformFeeCollector != address(0)) {
IERC20(weth).safeTransfer(platformFeeCollector, platformFee);
totalPlatformFees += platformFee;
emit PlatformFeeSent(poolId, platformFee, platformFeeCollector);
}
// Execute buyback with remaining amount
if (buybackAmount > 0) {
// Approve PoolManager
IERC20(weth).approve(poolManager, buybackAmount);
// Execute buyback via unlock
bytes memory data = abi.encode(key, buybackAmount, config.tokenAddress, poolId);
IPoolManager(poolManager).unlock(data);
}
}
function unlockCallback(bytes calldata data) external override returns (bytes memory) {
require(msg.sender == poolManager, "Not PoolManager");
(PoolKey memory key, uint256 buybackAmount, address tokenAddress, bytes32 poolId) =
abi.decode(data, (PoolKey, uint256, address, bytes32));
// Determine currencies
address currency1Addr = Currency.unwrap(key.currency1);
bool wethIsCurrency1 = currency1Addr == weth;
Currency wethCurrency = wethIsCurrency1 ? key.currency1 : key.currency0;
Currency tokenCurrency = wethIsCurrency1 ? key.currency0 : key.currency1;
// BUYBACK MODE: Buy tokens with WETH and burn
// zeroForOne = true if buying token0 with token1 (WETH)
bool zeroForOne = !wethIsCurrency1;
SwapParams memory swapParams = SwapParams({
zeroForOne: zeroForOne,
amountSpecified: -int256(buybackAmount), // Exact input (WETH)
sqrtPriceLimitX96: zeroForOne ? 4295128740 : 1461446703485210103287273052203988822378723970341
});
BalanceDelta swapDelta = IPoolManager(poolManager).swap(key, swapParams, "");
// Calculate tokens received
int128 amount0 = int128(int256(BalanceDelta.unwrap(swapDelta)) >> 128);
int128 amount1 = int128(int256(BalanceDelta.unwrap(swapDelta)));
int128 tokenDelta = wethIsCurrency1 ? amount0 : amount1;
uint256 tokensReceived = tokenDelta > 0 ? uint256(uint128(tokenDelta)) : 0;
// Settle WETH (we owe to the pool)
IPoolManager(poolManager).sync(wethCurrency);
IERC20(weth).transfer(poolManager, buybackAmount);
IPoolManager(poolManager).settle();
// Take tokens and burn
if (tokensReceived > 0) {
IPoolManager(poolManager).take(tokenCurrency, address(this), tokensReceived);
// Burn by sending to dead address
IERC20(tokenAddress).transfer(address(0xdead), tokensReceived);
totalBurned += tokensReceived;
}
totalBuybacks++;
emit BuybackExecuted(poolId, buybackAmount, tokensReceived);
return "";
}
// ============================================================
// VIEW FUNCTIONS
// ============================================================
function getPoolId(PoolKey calldata key) external pure returns (bytes32) {
return _getPoolId(key);
}
function _getPoolId(PoolKey calldata key) internal pure returns (bytes32) {
return keccak256(abi.encode(
Currency.unwrap(key.currency0),
Currency.unwrap(key.currency1),
key.fee,
key.tickSpacing,
address(key.hooks)
));
}
function getAccumulated(bytes32 poolId) external view returns (uint256) {
return taxConfigs[poolId].accumulated;
}
function isThresholdReached(bytes32 poolId) external view returns (bool) {
return taxConfigs[poolId].accumulated >= taxConfigs[poolId].threshold;
}
function getWethBalance() external view returns (uint256) {
return IERC20(weth).balanceOf(address(this));
}
function getPlatformFeeCollector() external view returns (address) {
return platformFeeCollector;
}
function getTotalPlatformFees() external view returns (uint256) {
return totalPlatformFees;
}
function getPlatformFeeBps() external view returns (uint256) {
return platformFeeBps;
}
receive() external payable {}
}
// ============================================================
// HOOKS LIBRARY
// ============================================================
library Hooks {
struct Permissions {
bool beforeInitialize;
bool afterInitialize;
bool beforeAddLiquidity;
bool afterAddLiquidity;
bool beforeRemoveLiquidity;
bool afterRemoveLiquidity;
bool beforeSwap;
bool afterSwap;
bool beforeDonate;
bool afterDonate;
bool beforeSwapReturnDelta;
bool afterSwapReturnDelta;
bool afterAddLiquidityReturnDelta;
bool afterRemoveLiquidityReturnDelta;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC1363.sol)
pragma solidity >=0.6.2;
import {IERC20} from "./IERC20.sol";
import {IERC165} from "./IERC165.sol";
/**
* @title IERC1363
* @dev Interface of the ERC-1363 standard as defined in the https://eips.ethereum.org/EIPS/eip-1363[ERC-1363].
*
* Defines an extension interface for ERC-20 tokens that supports executing code on a recipient contract
* after `transfer` or `transferFrom`, or code on a spender contract after `approve`, in a single transaction.
*/
interface IERC1363 is IERC20, IERC165 {
/*
* Note: the ERC-165 identifier for this interface is 0xb0202a11.
* 0xb0202a11 ===
* bytes4(keccak256('transferAndCall(address,uint256)')) ^
* bytes4(keccak256('transferAndCall(address,uint256,bytes)')) ^
* bytes4(keccak256('transferFromAndCall(address,address,uint256)')) ^
* bytes4(keccak256('transferFromAndCall(address,address,uint256,bytes)')) ^
* bytes4(keccak256('approveAndCall(address,uint256)')) ^
* bytes4(keccak256('approveAndCall(address,uint256,bytes)'))
*/
/**
* @dev Moves a `value` amount of tokens from the caller's account to `to`
* and then calls {IERC1363Receiver-onTransferReceived} on `to`.
* @param to The address which you want to transfer to.
* @param value The amount of tokens to be transferred.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function transferAndCall(address to, uint256 value) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from the caller's account to `to`
* and then calls {IERC1363Receiver-onTransferReceived} on `to`.
* @param to The address which you want to transfer to.
* @param value The amount of tokens to be transferred.
* @param data Additional data with no specified format, sent in call to `to`.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function transferAndCall(address to, uint256 value, bytes calldata data) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism
* and then calls {IERC1363Receiver-onTransferReceived} on `to`.
* @param from The address which you want to send tokens from.
* @param to The address which you want to transfer to.
* @param value The amount of tokens to be transferred.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function transferFromAndCall(address from, address to, uint256 value) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism
* and then calls {IERC1363Receiver-onTransferReceived} on `to`.
* @param from The address which you want to send tokens from.
* @param to The address which you want to transfer to.
* @param value The amount of tokens to be transferred.
* @param data Additional data with no specified format, sent in call to `to`.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function transferFromAndCall(address from, address to, uint256 value, bytes calldata data) external returns (bool);
/**
* @dev Sets a `value` amount of tokens as the allowance of `spender` over the
* caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`.
* @param spender The address which will spend the funds.
* @param value The amount of tokens to be spent.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function approveAndCall(address spender, uint256 value) external returns (bool);
/**
* @dev Sets a `value` amount of tokens as the allowance of `spender` over the
* caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`.
* @param spender The address which will spend the funds.
* @param value The amount of tokens to be spent.
* @param data Additional data with no specified format, sent in call to `spender`.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function approveAndCall(address spender, uint256 value, bytes calldata data) external returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC165.sol)
pragma solidity >=0.4.16;
import {IERC165} from "../utils/introspection/IERC165.sol";// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC20.sol)
pragma solidity >=0.4.16;
import {IERC20} from "../token/ERC20/IERC20.sol";// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC20/IERC20.sol)
pragma solidity >=0.4.16;
/**
* @dev Interface of the ERC-20 standard as defined in the ERC.
*/
interface IERC20 {
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
/**
* @dev Returns the value of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the value of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves a `value` amount of tokens from the caller's account to `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, uint256 value) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets a `value` amount of tokens as the allowance of `spender` over the
* caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 value) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the
* allowance mechanism. `value` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address from, address to, uint256 value) external returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.3.0) (token/ERC20/utils/SafeERC20.sol)
pragma solidity ^0.8.20;
import {IERC20} from "../IERC20.sol";
import {IERC1363} from "../../../interfaces/IERC1363.sol";
/**
* @title SafeERC20
* @dev Wrappers around ERC-20 operations that throw on failure (when the token
* contract returns false). Tokens that return no value (and instead revert or
* throw on failure) are also supported, non-reverting calls are assumed to be
* successful.
* To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/
library SafeERC20 {
/**
* @dev An operation with an ERC-20 token failed.
*/
error SafeERC20FailedOperation(address token);
/**
* @dev Indicates a failed `decreaseAllowance` request.
*/
error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease);
/**
* @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeTransfer(IERC20 token, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeCall(token.transfer, (to, value)));
}
/**
* @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the
* calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.
*/
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeCall(token.transferFrom, (from, to, value)));
}
/**
* @dev Variant of {safeTransfer} that returns a bool instead of reverting if the operation is not successful.
*/
function trySafeTransfer(IERC20 token, address to, uint256 value) internal returns (bool) {
return _callOptionalReturnBool(token, abi.encodeCall(token.transfer, (to, value)));
}
/**
* @dev Variant of {safeTransferFrom} that returns a bool instead of reverting if the operation is not successful.
*/
function trySafeTransferFrom(IERC20 token, address from, address to, uint256 value) internal returns (bool) {
return _callOptionalReturnBool(token, abi.encodeCall(token.transferFrom, (from, to, value)));
}
/**
* @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*
* IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the "client"
* smart contract uses ERC-7674 to set temporary allowances, then the "client" smart contract should avoid using
* this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract
* that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior.
*/
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 oldAllowance = token.allowance(address(this), spender);
forceApprove(token, spender, oldAllowance + value);
}
/**
* @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no
* value, non-reverting calls are assumed to be successful.
*
* IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the "client"
* smart contract uses ERC-7674 to set temporary allowances, then the "client" smart contract should avoid using
* this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract
* that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior.
*/
function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal {
unchecked {
uint256 currentAllowance = token.allowance(address(this), spender);
if (currentAllowance < requestedDecrease) {
revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease);
}
forceApprove(token, spender, currentAllowance - requestedDecrease);
}
}
/**
* @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval
* to be set to zero before setting it to a non-zero value, such as USDT.
*
* NOTE: If the token implements ERC-7674, this function will not modify any temporary allowance. This function
* only sets the "standard" allowance. Any temporary allowance will remain active, in addition to the value being
* set here.
*/
function forceApprove(IERC20 token, address spender, uint256 value) internal {
bytes memory approvalCall = abi.encodeCall(token.approve, (spender, value));
if (!_callOptionalReturnBool(token, approvalCall)) {
_callOptionalReturn(token, abi.encodeCall(token.approve, (spender, 0)));
_callOptionalReturn(token, approvalCall);
}
}
/**
* @dev Performs an {ERC1363} transferAndCall, with a fallback to the simple {ERC20} transfer if the target has no
* code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when
* targeting contracts.
*
* Reverts if the returned value is other than `true`.
*/
function transferAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal {
if (to.code.length == 0) {
safeTransfer(token, to, value);
} else if (!token.transferAndCall(to, value, data)) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @dev Performs an {ERC1363} transferFromAndCall, with a fallback to the simple {ERC20} transferFrom if the target
* has no code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when
* targeting contracts.
*
* Reverts if the returned value is other than `true`.
*/
function transferFromAndCallRelaxed(
IERC1363 token,
address from,
address to,
uint256 value,
bytes memory data
) internal {
if (to.code.length == 0) {
safeTransferFrom(token, from, to, value);
} else if (!token.transferFromAndCall(from, to, value, data)) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @dev Performs an {ERC1363} approveAndCall, with a fallback to the simple {ERC20} approve if the target has no
* code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when
* targeting contracts.
*
* NOTE: When the recipient address (`to`) has no code (i.e. is an EOA), this function behaves as {forceApprove}.
* Opposedly, when the recipient address (`to`) has code, this function only attempts to call {ERC1363-approveAndCall}
* once without retrying, and relies on the returned value to be true.
*
* Reverts if the returned value is other than `true`.
*/
function approveAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal {
if (to.code.length == 0) {
forceApprove(token, to, value);
} else if (!token.approveAndCall(to, value, data)) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*
* This is a variant of {_callOptionalReturnBool} that reverts if call fails to meet the requirements.
*/
function _callOptionalReturn(IERC20 token, bytes memory data) private {
uint256 returnSize;
uint256 returnValue;
assembly ("memory-safe") {
let success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20)
// bubble errors
if iszero(success) {
let ptr := mload(0x40)
returndatacopy(ptr, 0, returndatasize())
revert(ptr, returndatasize())
}
returnSize := returndatasize()
returnValue := mload(0)
}
if (returnSize == 0 ? address(token).code.length == 0 : returnValue != 1) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*
* This is a variant of {_callOptionalReturn} that silently catches all reverts and returns a bool instead.
*/
function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {
bool success;
uint256 returnSize;
uint256 returnValue;
assembly ("memory-safe") {
success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20)
returnSize := returndatasize()
returnValue := mload(0)
}
return success && (returnSize == 0 ? address(token).code.length > 0 : returnValue == 1);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (utils/introspection/IERC165.sol)
pragma solidity >=0.4.16;
/**
* @dev Interface of the ERC-165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[ERC].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165 {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}// SPDX-License-Identifier: MIT
// Qian Exchange - https://qian.ag
pragma solidity ^0.8.24;
/// @notice Currency type for Uniswap V4
/// Wraps an address to represent a token or native ETH
type Currency is address;
/// @notice Currency library for V4
library CurrencyLibrary {
/// @notice Wrap an address as Currency
function wrap(address token) internal pure returns (Currency) {
return Currency.wrap(token);
}
/// @notice Unwrap Currency to address
function unwrap(Currency currency) internal pure returns (address) {
return Currency.unwrap(currency);
}
/// @notice Native ETH currency
function native() internal pure returns (Currency) {
return Currency.wrap(address(0));
}
/// @notice Check if currency is native ETH
function isNative(Currency currency) internal pure returns (bool) {
return Currency.unwrap(currency) == address(0);
}
}// SPDX-License-Identifier: MIT
// Qian Exchange - https://qian.ag
pragma solidity ^0.8.24;
import "./IPoolManager.sol";
/// @notice Swap parameters for hook callbacks
struct SwapParams {
bool zeroForOne;
int256 amountSpecified;
uint160 sqrtPriceLimitX96;
}
/// @notice Uniswap V4 Hooks interface
/// Hooks can implement various callbacks to customize pool behavior
interface IHooks {
/// @notice Called before a pool is initialized
function beforeInitialize(address sender, PoolKey calldata key, uint160 sqrtPriceX96) external returns (bytes4);
/// @notice Called after a pool is initialized
function afterInitialize(address sender, PoolKey calldata key, uint160 sqrtPriceX96, int24 tick) external returns (bytes4);
/// @notice Called before a swap
function beforeSwap(address sender, PoolKey calldata key, SwapParams calldata params, bytes calldata hookData) external returns (bytes4, BeforeSwapDelta, uint24);
/// @notice Called after a swap
function afterSwap(address sender, PoolKey calldata key, SwapParams calldata params, BalanceDelta delta, bytes calldata hookData) external returns (bytes4, int128);
/// @notice Called before liquidity is added
function beforeAddLiquidity(address sender, PoolKey calldata key, ModifyLiquidityParams calldata params, bytes calldata hookData) external returns (bytes4);
/// @notice Called after liquidity is added
function afterAddLiquidity(address sender, PoolKey calldata key, ModifyLiquidityParams calldata params, BalanceDelta delta, BalanceDelta feesAccrued, bytes calldata hookData) external returns (bytes4, BalanceDelta);
/// @notice Called before liquidity is removed
function beforeRemoveLiquidity(address sender, PoolKey calldata key, ModifyLiquidityParams calldata params, bytes calldata hookData) external returns (bytes4);
/// @notice Called after liquidity is removed
function afterRemoveLiquidity(address sender, PoolKey calldata key, ModifyLiquidityParams calldata params, BalanceDelta delta, BalanceDelta feesAccrued, bytes calldata hookData) external returns (bytes4, BalanceDelta);
/// @notice Called before a donate
function beforeDonate(address sender, PoolKey calldata key, uint256 amount0, uint256 amount1, bytes calldata hookData) external returns (bytes4);
/// @notice Called after a donate
function afterDonate(address sender, PoolKey calldata key, uint256 amount0, uint256 amount1, bytes calldata hookData) external returns (bytes4);
}
/// @notice Before swap delta type - encodes (specifiedDelta, unspecifiedDelta)
type BeforeSwapDelta is int256;// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
import "./ICurrency.sol";
import "./IHooks.sol";
// BalanceDelta is a packed int256 where:
// - Upper 128 bits = amount0 (int128)
// - Lower 128 bits = amount1 (int128)
type BalanceDelta is int256;
/// @notice Library for getting amount0/amount1 from BalanceDelta
library BalanceDeltaLibrary {
function amount0(BalanceDelta balanceDelta) internal pure returns (int128 _amount0) {
assembly ("memory-safe") {
_amount0 := sar(128, balanceDelta)
}
}
function amount1(BalanceDelta balanceDelta) internal pure returns (int128 _amount1) {
assembly ("memory-safe") {
_amount1 := signextend(15, balanceDelta)
}
}
}
/// @notice PoolKey identifies a V4 pool
struct PoolKey {
Currency currency0;
Currency currency1;
uint24 fee;
int24 tickSpacing;
IHooks hooks;
}
/// @notice Parameters for modifyLiquidity
struct ModifyLiquidityParams {
int24 tickLower;
int24 tickUpper;
int256 liquidityDelta;
bytes32 salt;
}
/// @notice Interface for Uniswap V4 PoolManager
interface IPoolManager {
/// @notice Initialize the state for a given pool
function initialize(PoolKey memory key, uint160 sqrtPriceX96) external returns (int24 tick);
/// @notice Modify the liquidity for the given pool
function modifyLiquidity(PoolKey memory key, ModifyLiquidityParams memory params, bytes calldata hookData)
external
returns (BalanceDelta callerDelta, BalanceDelta feesAccrued);
/// @notice All interactions on the contract that account deltas require unlocking
function unlock(bytes calldata data) external returns (bytes memory);
/// @notice Sync the currency to its current balance in the PoolManager
function sync(Currency currency) external;
/// @notice Settle the currency, paying what is owed
function settle() external payable returns (uint256 paid);
/// @notice Take currency from the PoolManager
/// @param currency The currency to take
/// @param to The address to receive the currency
/// @param amount The amount to take
function take(Currency currency, address to, uint256 amount) external;
/// @notice Execute a swap
/// @param key The pool key
/// @param params The swap parameters
/// @param hookData Any data to be passed to hooks
function swap(PoolKey memory key, SwapParams memory params, bytes calldata hookData)
external
returns (BalanceDelta swapDelta);
}// SPDX-License-Identifier: MIT
// Qian Exchange - https://qian.ag
pragma solidity ^0.8.24;
/// @notice Interface for the callback executed when an address unlocks the pool manager
interface IUnlockCallback {
/// @notice Called by the pool manager on `msg.sender` when the manager is unlocked
/// @param data The data that was passed to the call to unlock
/// @return Any data that you want to be returned from the unlock call
function unlockCallback(bytes calldata data) external returns (bytes memory);
}{
"optimizer": {
"enabled": true,
"runs": 100
},
"viaIR": true,
"evmVersion": "paris",
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_poolManager","type":"address"},{"internalType":"address","name":"_weth","type":"address"},{"internalType":"address","name":"_controller","type":"address"},{"internalType":"address","name":"_platformFeeCollector","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"InvalidAddress","type":"error"},{"inputs":[],"name":"InvalidPlatformFee","type":"error"},{"inputs":[],"name":"InvalidTax","type":"error"},{"inputs":[],"name":"InvalidThreshold","type":"error"},{"inputs":[],"name":"NotController","type":"error"},{"inputs":[],"name":"NotPoolManager","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"SafeERC20FailedOperation","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"poolId","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"wethSpent","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"tokensBurned","type":"uint256"}],"name":"BuybackExecuted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldBps","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newBps","type":"uint256"}],"name":"PlatformFeeBpsUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldCollector","type":"address"},{"indexed":false,"internalType":"address","name":"newCollector","type":"address"}],"name":"PlatformFeeCollectorUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"poolId","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"wethAmount","type":"uint256"},{"indexed":false,"internalType":"address","name":"recipient","type":"address"}],"name":"PlatformFeeSent","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"poolId","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"bool","name":"isBuy","type":"bool"}],"name":"TaxTaken","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"poolId","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"accumulated","type":"uint256"}],"name":"ThresholdReached","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"poolId","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"tokensSpent","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"wethReceived","type":"uint256"}],"name":"TokensConvertedToWeth","type":"event"},{"inputs":[],"name":"FEE_DENOMINATOR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_PLATFORM_FEE_BPS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_TAX_BPS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"components":[{"internalType":"Currency","name":"currency0","type":"address"},{"internalType":"Currency","name":"currency1","type":"address"},{"internalType":"uint24","name":"fee","type":"uint24"},{"internalType":"int24","name":"tickSpacing","type":"int24"},{"internalType":"contract IHooks","name":"hooks","type":"address"}],"internalType":"struct PoolKey","name":"","type":"tuple"},{"components":[{"internalType":"int24","name":"tickLower","type":"int24"},{"internalType":"int24","name":"tickUpper","type":"int24"},{"internalType":"int256","name":"liquidityDelta","type":"int256"},{"internalType":"bytes32","name":"salt","type":"bytes32"}],"internalType":"struct ModifyLiquidityParams","name":"","type":"tuple"},{"internalType":"BalanceDelta","name":"","type":"int256"},{"internalType":"BalanceDelta","name":"","type":"int256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"afterAddLiquidity","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"},{"internalType":"BalanceDelta","name":"","type":"int256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"components":[{"internalType":"Currency","name":"currency0","type":"address"},{"internalType":"Currency","name":"currency1","type":"address"},{"internalType":"uint24","name":"fee","type":"uint24"},{"internalType":"int24","name":"tickSpacing","type":"int24"},{"internalType":"contract IHooks","name":"hooks","type":"address"}],"internalType":"struct PoolKey","name":"","type":"tuple"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"afterDonate","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"components":[{"internalType":"Currency","name":"currency0","type":"address"},{"internalType":"Currency","name":"currency1","type":"address"},{"internalType":"uint24","name":"fee","type":"uint24"},{"internalType":"int24","name":"tickSpacing","type":"int24"},{"internalType":"contract IHooks","name":"hooks","type":"address"}],"internalType":"struct PoolKey","name":"","type":"tuple"},{"internalType":"uint160","name":"","type":"uint160"},{"internalType":"int24","name":"","type":"int24"}],"name":"afterInitialize","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"components":[{"internalType":"Currency","name":"currency0","type":"address"},{"internalType":"Currency","name":"currency1","type":"address"},{"internalType":"uint24","name":"fee","type":"uint24"},{"internalType":"int24","name":"tickSpacing","type":"int24"},{"internalType":"contract IHooks","name":"hooks","type":"address"}],"internalType":"struct PoolKey","name":"","type":"tuple"},{"components":[{"internalType":"int24","name":"tickLower","type":"int24"},{"internalType":"int24","name":"tickUpper","type":"int24"},{"internalType":"int256","name":"liquidityDelta","type":"int256"},{"internalType":"bytes32","name":"salt","type":"bytes32"}],"internalType":"struct ModifyLiquidityParams","name":"","type":"tuple"},{"internalType":"BalanceDelta","name":"","type":"int256"},{"internalType":"BalanceDelta","name":"","type":"int256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"afterRemoveLiquidity","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"},{"internalType":"BalanceDelta","name":"","type":"int256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"components":[{"internalType":"Currency","name":"currency0","type":"address"},{"internalType":"Currency","name":"currency1","type":"address"},{"internalType":"uint24","name":"fee","type":"uint24"},{"internalType":"int24","name":"tickSpacing","type":"int24"},{"internalType":"contract IHooks","name":"hooks","type":"address"}],"internalType":"struct PoolKey","name":"key","type":"tuple"},{"components":[{"internalType":"bool","name":"zeroForOne","type":"bool"},{"internalType":"int256","name":"amountSpecified","type":"int256"},{"internalType":"uint160","name":"sqrtPriceLimitX96","type":"uint160"}],"internalType":"struct SwapParams","name":"params","type":"tuple"},{"internalType":"BalanceDelta","name":"delta","type":"int256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"afterSwap","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"},{"internalType":"int128","name":"","type":"int128"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"components":[{"internalType":"Currency","name":"currency0","type":"address"},{"internalType":"Currency","name":"currency1","type":"address"},{"internalType":"uint24","name":"fee","type":"uint24"},{"internalType":"int24","name":"tickSpacing","type":"int24"},{"internalType":"contract IHooks","name":"hooks","type":"address"}],"internalType":"struct PoolKey","name":"","type":"tuple"},{"components":[{"internalType":"int24","name":"tickLower","type":"int24"},{"internalType":"int24","name":"tickUpper","type":"int24"},{"internalType":"int256","name":"liquidityDelta","type":"int256"},{"internalType":"bytes32","name":"salt","type":"bytes32"}],"internalType":"struct ModifyLiquidityParams","name":"","type":"tuple"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"beforeAddLiquidity","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"components":[{"internalType":"Currency","name":"currency0","type":"address"},{"internalType":"Currency","name":"currency1","type":"address"},{"internalType":"uint24","name":"fee","type":"uint24"},{"internalType":"int24","name":"tickSpacing","type":"int24"},{"internalType":"contract IHooks","name":"hooks","type":"address"}],"internalType":"struct PoolKey","name":"","type":"tuple"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"beforeDonate","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"components":[{"internalType":"Currency","name":"currency0","type":"address"},{"internalType":"Currency","name":"currency1","type":"address"},{"internalType":"uint24","name":"fee","type":"uint24"},{"internalType":"int24","name":"tickSpacing","type":"int24"},{"internalType":"contract IHooks","name":"hooks","type":"address"}],"internalType":"struct PoolKey","name":"","type":"tuple"},{"internalType":"uint160","name":"","type":"uint160"}],"name":"beforeInitialize","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"components":[{"internalType":"Currency","name":"currency0","type":"address"},{"internalType":"Currency","name":"currency1","type":"address"},{"internalType":"uint24","name":"fee","type":"uint24"},{"internalType":"int24","name":"tickSpacing","type":"int24"},{"internalType":"contract IHooks","name":"hooks","type":"address"}],"internalType":"struct PoolKey","name":"","type":"tuple"},{"components":[{"internalType":"int24","name":"tickLower","type":"int24"},{"internalType":"int24","name":"tickUpper","type":"int24"},{"internalType":"int256","name":"liquidityDelta","type":"int256"},{"internalType":"bytes32","name":"salt","type":"bytes32"}],"internalType":"struct ModifyLiquidityParams","name":"","type":"tuple"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"beforeRemoveLiquidity","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"components":[{"internalType":"Currency","name":"currency0","type":"address"},{"internalType":"Currency","name":"currency1","type":"address"},{"internalType":"uint24","name":"fee","type":"uint24"},{"internalType":"int24","name":"tickSpacing","type":"int24"},{"internalType":"contract IHooks","name":"hooks","type":"address"}],"internalType":"struct PoolKey","name":"key","type":"tuple"},{"components":[{"internalType":"bool","name":"zeroForOne","type":"bool"},{"internalType":"int256","name":"amountSpecified","type":"int256"},{"internalType":"uint160","name":"sqrtPriceLimitX96","type":"uint160"}],"internalType":"struct SwapParams","name":"params","type":"tuple"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"beforeSwap","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"},{"internalType":"BeforeSwapDelta","name":"","type":"int256"},{"internalType":"uint24","name":"","type":"uint24"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"poolId","type":"bytes32"},{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint16","name":"buyTaxBps","type":"uint16"},{"internalType":"uint16","name":"sellTaxBps","type":"uint16"},{"internalType":"uint256","name":"threshold","type":"uint256"}],"name":"configureSnowball","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"controller","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"Currency","name":"currency0","type":"address"},{"internalType":"Currency","name":"currency1","type":"address"},{"internalType":"uint24","name":"fee","type":"uint24"},{"internalType":"int24","name":"tickSpacing","type":"int24"},{"internalType":"contract IHooks","name":"hooks","type":"address"}],"internalType":"struct PoolKey","name":"key","type":"tuple"}],"name":"executeBuyback","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"factory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"poolId","type":"bytes32"}],"name":"getAccumulated","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getHookPermissions","outputs":[{"components":[{"internalType":"bool","name":"beforeInitialize","type":"bool"},{"internalType":"bool","name":"afterInitialize","type":"bool"},{"internalType":"bool","name":"beforeAddLiquidity","type":"bool"},{"internalType":"bool","name":"afterAddLiquidity","type":"bool"},{"internalType":"bool","name":"beforeRemoveLiquidity","type":"bool"},{"internalType":"bool","name":"afterRemoveLiquidity","type":"bool"},{"internalType":"bool","name":"beforeSwap","type":"bool"},{"internalType":"bool","name":"afterSwap","type":"bool"},{"internalType":"bool","name":"beforeDonate","type":"bool"},{"internalType":"bool","name":"afterDonate","type":"bool"},{"internalType":"bool","name":"beforeSwapReturnDelta","type":"bool"},{"internalType":"bool","name":"afterSwapReturnDelta","type":"bool"},{"internalType":"bool","name":"afterAddLiquidityReturnDelta","type":"bool"},{"internalType":"bool","name":"afterRemoveLiquidityReturnDelta","type":"bool"}],"internalType":"struct Hooks.Permissions","name":"","type":"tuple"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getPlatformFeeBps","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPlatformFeeCollector","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"Currency","name":"currency0","type":"address"},{"internalType":"Currency","name":"currency1","type":"address"},{"internalType":"uint24","name":"fee","type":"uint24"},{"internalType":"int24","name":"tickSpacing","type":"int24"},{"internalType":"contract IHooks","name":"hooks","type":"address"}],"internalType":"struct PoolKey","name":"key","type":"tuple"}],"name":"getPoolId","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getTotalPlatformFees","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getWethBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"poolId","type":"bytes32"}],"name":"isThresholdReached","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"platformFeeBps","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"platformFeeCollector","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"poolManager","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newController","type":"address"}],"name":"setController","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"poolId","type":"bytes32"},{"internalType":"bool","name":"enabled","type":"bool"}],"name":"setEnabled","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newFactory","type":"address"}],"name":"setFactory","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newPlatformFeeBps","type":"uint256"}],"name":"setPlatformFeeBps","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newCollector","type":"address"}],"name":"setPlatformFeeCollector","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"taxConfigs","outputs":[{"internalType":"uint16","name":"buyTaxBps","type":"uint16"},{"internalType":"uint16","name":"sellTaxBps","type":"uint16"},{"internalType":"uint256","name":"threshold","type":"uint256"},{"internalType":"uint256","name":"accumulated","type":"uint256"},{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"bool","name":"enabled","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"tokenFeesAccumulated","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalBurned","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalBuybacks","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalPlatformFees","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"data","type":"bytes"}],"name":"unlockCallback","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"poolId","type":"bytes32"},{"internalType":"uint16","name":"buyTaxBps","type":"uint16"},{"internalType":"uint16","name":"sellTaxBps","type":"uint16"}],"name":"updateTaxRates","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"weth","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]Contract Creation Code
60c0346200015f57601f6200251938819003918201601f19168301916001600160401b0383118484101762000164578084926080946040528339810103126200015f576200004d816200017a565b6200005b602083016200017a565b6200007760606200006f604086016200017a565b94016200017a565b9160805260a05260018060a01b03908160018060a01b03199316836000541617600055169060015416176001556107d0600355604051612389908162000190823960805181818161054d01528181610b3601528181610daa01528181610e2b01528181610e8401528181610eca01528181610f570152818161102c015281816110820152818161167701528181611d740152611fcc015260a051818181610a1701528181610c1501528181610c4001528181610c8a01528181610cef01528181610ddd01528181610f0b015281816114d8015281816115cf01528181611dd6015261202f0152f35b600080fd5b634e487b7160e01b600052604160045260246000fd5b51906001600160a01b03821682036200015f5756fe608080604052600436101561001d575b50361561001b57600080fd5b005b600090813560e01c90816321d0ee7014611a405750806322dcd13e1461152457806322ebb0f814611567578063259982e51461154257806326e3c685146115245780632c597de91461150757806331521d57146105e15780633fc8cef3146114c25780634c1a69001461148d578063575e24b4146114095780635bb47808146113c7578063602cf5731461136a5780636c2bbe7e1461133d5780636fe7e6eb146112ee578063853a65f91461084d5780638d01513c146112d157806391dd734614610b0357806392eefe9b14610abc5780639c6b88a814610a985780639dd58b58146109ea5780639f063efc146109bd578063a97edea81461094b578063ade41d501461091e578063b47b2fb11461089c578063b6a8b0fa14610876578063bb1f60d01461084d578063c45a015514610824578063c4e833ce14610699578063c580c9421461061d578063cb371f83146105ff578063d3631fa5146105e1578063d427ceaa146105b7578063d73792a91461059a578063d89135cd1461057c578063dc4c90d314610537578063dc98354e146104f5578063dd98d7c11461037a578063dfc90cf2146102eb578063e1b4af69146102c5578063eb9912e0146102125763f77c47910361000f573461020f578060031936011261020f57546040516001600160a01b039091168152602090f35b80fd5b503461020f57606036600319011261020f5760243561ffff8082168092036102c05761023c611c59565b83549091906001600160a01b031633036102ae576105dc9081841161029c5782161161029c5760048035845260205260408320805463ffff00001990931663ffffffff199093169290921760109190911b63ffff00001617905580f35b80f35b6040516337d4ed5b60e01b8152600490fd5b6040516323019e6760e01b8152600490fd5b600080fd5b503461020f576102d436611c02565b505050505050602060405163e1b4af6960e01b8152f35b503461020f57602036600319011261020f57610305611a64565b81546001600160a01b039190821633036102ae5781168015610368577fb4e31e50e03f47b5be13be5942bd3a5b1b6048e886cfd1ce1932910251b2958e91604091600154918160018060a01b03198416176001558351921682526020820152a180f35b60405163e6c4247b60e01b8152600490fd5b503461020f5760a036600319011261020f57600435610397611a7a565b61039f611c59565b916064359261ffff8085168095036102c05785546001600160a01b039260843592918416331415806104e7575b6102ae578116916105dc80841161029c57871161029c5780156104d55784885260046020526002604089200154906040519260c08401908482106001600160401b038311176104bf576102999960039661048293604052865260208601908152604086019384526060860194855287608087019a168a5260a086019860018a528c5260046020528160408d2096511661ffff198754161786555116849063ffff000082549160101b169063ffff00001916179055565b516001830155516002820155935193018054925160ff60a01b90151560a01b166001600160a81b03199093169190931660ff60a01b191617179055565b634e487b7160e01b600052604160045260246000fd5b60405163aabd5a0960e01b8152600490fd5b5083600254163314156103cc565b503461020f5760e036600319011261020f5761050f611a64565b5060a036602319011261020f57610524611b9d565b50604051636e4c1aa760e11b8152602090f35b503461020f578060031936011261020f576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b503461020f578060031936011261020f576020600654604051908152f35b503461020f578060031936011261020f5760206040516127108152f35b503461020f57602036600319011261020f5760406020916004358152600983522054604051908152f35b503461020f578060031936011261020f576020600754604051908152f35b503461020f578060031936011261020f576020600554604051908152f35b503461020f57602036600319011261020f578054600435906001600160a01b031633036102ae5761138881116106875760407fb7cf940f291738114d642ccbcbdedeeeddc0bb17e043b90365614d7159129d7191600354908060035582519182526020820152a180f35b60405163183440b760e31b8152600490fd5b503461020f578060031936011261020f57806101c0916101a06040516106be81611c7d565b8281528260208201528260408201528260608201528260808201528260a08201528260c08201528260e0820152826101008201528261012082015282610140820152826101608201528261018082015201526101a060405161071f81611c7d565b8281528260208201528260408201528260608201528260808201528260a0820152600160c0820152600160e082015282610100820152826101208201526001610140820152600161016082015282610180820152828282015260405192835260208101511515602084015260408101511515604084015260608101511515606084015260808101511515608084015260a0810151151560a084015260c0810151151560c084015260e0810151151560e084015261010081015115156101008401526101208101511515610120840152610140810151151561014084015261016081015115156101608401526101808101511515610180840152015115156101a0820152f35b503461020f578060031936011261020f576002546040516001600160a01b039091168152602090f35b503461020f578060031936011261020f576001546040516001600160a01b039091168152602090f35b503461020f5761088536611c02565b5050505050506020604051635b54587d60e11b8152f35b503461020f5761016036600319011261020f576108b7611a64565b5060a036602319011261020f5760603660c319011261020f57610144356001600160401b03811161091a576108f0903690600401611aa4565b5050604061090061012435611fc1565b82516001600160e01b03199092168252600f0b6020820152f35b5080fd5b503461020f57602036600319011261020f5760026040602092600435815260048452200154604051908152f35b503461020f57602036600319011261020f57604060c091600435815260046020522060ff81549161ffff906001810154600360028301549201549260405195818116875260101c1660208601526040850152606084015260018060a01b038116608084015260a01c16151560a0820152f35b503461020f576109cc36611b34565b50505050505050604080516327c18fbf60e21b815260006020820152f35b503461020f578060031936011261020f576040516370a0823160e01b8152306004820152906020826024817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa908115610a8c5790610a59575b602090604051908152f35b506020813d602011610a84575b81610a7360209383611cb4565b810103126102c05760209051610a4e565b3d9150610a66565b604051903d90823e3d90fd5b503461020f5760a036600319011261020f576020610ab4612255565b604051908152f35b503461020f57602036600319011261020f57610ad6611a64565b8154906001600160a01b039081831633036102ae5716908115610368576001600160a01b03191617815580f35b503461020f57602036600319011261020f576004356001600160401b03811161091a57610b34903690600401611aa4565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316330361129a57819081010361010081126111555760a01361091a576040519060a082018281106001600160401b0382111761128657604052610b9f81611a90565b91828152610baf60208301611a90565b806020830152604083013562ffffff811681036111d657604083015260608301358060020b81036111d6576060830152610beb60808401611a90565b608083015260c0830135906001600160a01b03821682036111d6576001600160a01b0390811692907f00000000000000000000000000000000000000000000000000000000000000001683036112765782945b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316840361126f576001600160a01b0316925b60a0850135600160ff1b1461125b577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168114611241576401000276a45b604051908160608101106001600160401b0360608401111761122d57606082810160409081526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116861415855260a08a01358c0360208087019182529482168387019081528351633cf3645360e21b815289518416600482015289870151841660248201529389015162ffffff1660448501529388015160020b6064840152608090970151811660848301529351151560a4820152945160c486015251821660e485015261012061010485015261012484018990529083906101449082908b907f0000000000000000000000000000000000000000000000000000000000000000165af19182156112225787926111ea575b507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316036111e25760801d600f0b5b8581600f0b136000146111da576001600160801b0316935b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03163b156111d657604051632961046560e21b81526001600160a01b0391821660048201529086908290602490829084907f0000000000000000000000000000000000000000000000000000000000000000165af180156111cb576111b6575b5060405163a9059cbb60e01b8082526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016600483015260a08501356024830152869390929160208180604481010381887f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165af1801561118c57611197575b50604051630476982d60e21b8152602081600481887f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165af1801561118c5761115d575b508561102a575b5050505060055460001981146110165760e07f9ff78e7c440e5fcb39d1e846ff16b1e3ab6ba799bf89e6e5b33cab8fe5df891a9260016040930160055582519460a082013586526020860152013592a260405160208101918183106001600160401b038411176104bf5761101292604052815260405191829182611bd6565b0390f35b634e487b7160e01b84526011600452602484fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03163b1561115957838661107d926040519384928392630b0d9c0960e01b8452309060048501611d48565b0381837f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165af1908115611136578491611141575b505060446020926040519485938492835261dead600484015288602484015260018060a01b03165af1801561113657611107575b506110fb82600654611d0b565b60065582388080610f93565b6111289060203d60201161112f575b6111208183611cb4565b810190611d18565b50386110ee565b503d611116565b6040513d86823e3d90fd5b61114a90611c6a565b6111555782386110ba565b8280fd5b8380fd5b6020809295503d8311611185575b6111758183611cb4565b810103126102c057859238610f8c565b503d61116b565b6040513d87823e3d90fd5b6111af9060203d60201161112f576111208183611cb4565b5038610f40565b6111c39095919295611c6a565b939038610eb1565b6040513d88823e3d90fd5b8580fd5b508493610e29565b600f0b610e11565b9091506020813d60201161121a575b8161120660209383611cb4565b8101031261121657519038610dda565b8680fd5b3d91506111f9565b6040513d89823e3d90fd5b634e487b7160e01b89526041600452602489fd5b73fffd8963efd1fc6a506488495d951d5263988d25610cbf565b634e487b7160e01b87526011600452602487fd5b5082610c79565b6001600160a01b03851694610c3e565b634e487b7160e01b84526041600452602484fd5b60405162461bcd60e51b815260206004820152600f60248201526e2737ba102837b7b626b0b730b3b2b960891b6044820152606490fd5b503461020f578060031936011261020f5760206040516113888152f35b503461020f5761010036600319011261020f57611309611a64565b5060a036602319011261020f5761131e611b9d565b5060e4358060020b0361020f57604051636fe7e6eb60e01b8152602090f35b503461020f5760409061134f36611b34565b50505050505050815190633615df3f60e11b82526020820152f35b503461020f57604036600319011261020f57602435801515810361091a5781546001600160a01b031633036102ae5760048035835260205260408220600301805460ff60a01b191691151560a01b60ff60a01b1691909117905580f35b503461020f57602036600319011261020f576113e1611a64565b81546001600160a01b039190821633036102ae571660018060a01b0319600254161760025580f35b503461020f5761014036600319011261020f57611424611a64565b5060a036602319011261020f5760603660c319011261020f57610124356001600160401b03811161091a5761145d903690600401611aa4565b5050606062ffffff61146d611d6a565b906040939293519363ffffffff60e01b1684526020840152166040820152f35b503461020f57602036600319011261020f57604060209160043581526004835220600160028201549101541115604051908152f35b503461020f578060031936011261020f576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b503461020f578060031936011261020f5760206040516105dc8152f35b503461020f578060031936011261020f576020600354604051908152f35b503461020f5761155136611ad1565b5050505050602060405163259982e560e01b8152f35b503461020f5760a036600319011261020f57611581612255565b80825260206004815260408320600381019260ff845460a01c1615611a0d5760028201926001845493015483106119d1576040516370a0823160e01b81523060048201526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811696602496919492909190848189818c5afa9081156119c6578a91611999575b508015611960578681101561195957955b86808211156119505761163291611cd5565b905b5561164f61271061164760035488611cf8565b048096611cd5565b9480151580611943575b611869575b5084611668578780f35b60405163095ea7b360e01b81527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b038116600483015260248201879052979091908490839060449082908d905af191821561185e578592611841575b50541660405194846116db611a64565b1684870152846116e9611a7a565b16604087015260443562ffffff811680910361183d5760608701526064358060020b80910361183d57608087015260843585811680910361183d5760a087015260c086015260e08501526101009081850152835261012092838101956001600160401b03938288108589111761182a57889188838193826040526348c8949160e01b835261011f1987611780816101248101611bd6565b030193165af180156112225761179557808780f35b3d8088883e6117a48188611cb4565b81019582828689019803126118265751908382116118265701928561013f8501121561121657830151936101409285116118145750604051946117f0601f8601601f1916830187611cb4565b8486528285850101116111d65761180994019101611bb3565b388080808080808780f35b634e487b7160e01b8752604160045286fd5b8780fd5b634e487b7160e01b895260416004528689fd5b8980fd5b61185790853d871161112f576111208183611cb4565b50386116cb565b6040513d8b823e3d90fd5b6001546040805163a9059cbb60e01b8782019081529288166001600160a01b03168a82019081526020810185905287938d939092916118b39183910103601f198101835282611cb4565b5190828c5af1156119385788513d61192f5750873b155b611917577f57982d28adf5212b25ddfe8de7bc312243fa25e94b54db636b0371290f648fcc6040826118ff8694600754611d0b565b6007558760015416825191825287820152a23861165e565b604051635274afe760e01b8152600481018990528790fd5b600114156118ca565b6040513d8a823e3d90fd5b5084600154161515611659565b50508890611634565b5085611620565b60405162461bcd60e51b8152600481018690526012818a0152714e6f205745544820746f206275796261636b60701b6044820152606490fd5b90508481813d83116119bf575b6119b08183611cb4565b8101031261183d57513861160f565b503d6119a6565b6040513d8c823e3d90fd5b6064906040519062461bcd60e51b825260048201526015602482015274151a1c995cda1bdb19081b9bdd081c995858da1959605a1b6044820152fd5b60405162461bcd60e51b815260048101849052600b60248201526a139bdd08195b98589b195960aa1b6044820152606490fd5b90503461091a57602090611a5336611ad1565b505063021d0ee760e41b8452505050f35b600435906001600160a01b03821682036102c057565b602435906001600160a01b03821682036102c057565b35906001600160a01b03821682036102c057565b9181601f840112156102c0578235916001600160401b0383116102c057602083818601950101116102c057565b906101606003198301126102c0576004356001600160a01b03811681036102c0579160a06023198201126102c057602491608060c3198301126102c05760c49161014435906001600160401b0382116102c057611b3091600401611aa4565b9091565b906101a06003198301126102c0576004356001600160a01b03811681036102c0579160a06023198201126102c057602491608060c3198301126102c05760c4916101443591610164359161018435906001600160401b0382116102c057611b3091600401611aa4565b60c435906001600160a01b03821682036102c057565b60005b838110611bc65750506000910152565b8181015183820152602001611bb6565b60409160208252611bf68151809281602086015260208686019101611bb3565b601f01601f1916010190565b6101206003198201126102c0576004356001600160a01b03811681036102c0579160a06023198301126102c05760249160c4359160e4359161010435906001600160401b0382116102c057611b3091600401611aa4565b6044359061ffff821682036102c057565b6001600160401b0381116104bf57604052565b6101c081019081106001600160401b038211176104bf57604052565b60c081019081106001600160401b038211176104bf57604052565b90601f801991011681019081106001600160401b038211176104bf57604052565b91908203918211611ce257565b634e487b7160e01b600052601160045260246000fd5b81810292918115918404141715611ce257565b91908201809211611ce257565b908160209103126102c0575180151581036102c05790565b600f0b60016001607f1b03198114611ce25760000390565b6001600160a01b03918216815291166020820152604081019190915260600190565b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081169033829003611faf57611da66122d7565b9160009280845260046020526040842060ff600382015460a01c1615611f9d5760443592848416808503611216577f0000000000000000000000000000000000000000000000000000000000000000861614938415611f8d5760c435801590811503611826575b611e26575b506315d7892d60e21b968695509350505050565b61ffff835416958615611f7857612710611e6460e435988a8a12998a600014611f6a576001600160801b0390611e5e90600f0b611d30565b16611cf8565b049586611e72575050611e12565b96989615611f5957505b813b156112165784611ea992889283604051809681958294630b0d9c0960e01b8452309060048501611d48565b03925af180156111cb57611f45575b50600201611ec7838254611d0b565b90557f9cae4344a2aa90b3dbc6528a3f2ffaed048544717fac552b75ee12618278d7076040805184815260016020820152a28315611f3e576001600160801b038116600f0b935b15611f2c575081925b6315d7892d60e21b93600f0b9060801b179190565b6001600160801b0316600f0b92611f17565b8293611f0e565b94611f5260029296611c6a565b9490611eb8565b602435915081168114611e7c578680fd5b6001600160801b0316611cf8565b506315d7892d60e21b97879650945050505050565b60c4358015158114611e0d578780fd5b506315d7892d60e21b94849350915050565b60405163570c108560e11b8152600490fd5b906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811633819003611faf57611ffd6122d7565b9160009083825260046020526040918281209360ff600386015460a01c161561224257604435838116808203611159577f000000000000000000000000000000000000000000000000000000000000000085161493841561222f5760c435801515810361222b57995b849a8061221a575b6120cd575b5050505050506001600283015492015482101561209b575b5063b47b2fb160e01b9392915050565b7fed9753748c66ee1df3e83ee8ba5d83244f01c004097e0e4eebd94e5fd6fea5f19160209151908152a238808061208b565b851561220f57600f0b5b8481600f0b8181136000146121ea5750506001600160801b03165b80156120735761210e6127109161ffff8a5460101c1690611cf8565b0494851561207357909192938095969a50506000146121d957505b813b156111555783612155928492838b51809681958294630b0d9c0960e01b8452309060048501611d48565b03925af180156121cf5785927f9cae4344a2aa90b3dbc6528a3f2ffaed048544717fac552b75ee12618278d7079289926121c0575b506002860161219a868254611d0b565b90558151908582526020820152a26001600160801b0316600f0b93388080808080612073565b6121c990611c6a565b3861218a565b87513d84823e3d90fd5b602435915081168114612129578280fd5b1215612208576001600160801b039061220290611d30565b166120f2565b50836120f2565b60801d600f0b6120d7565b5061ffff885460101c16151561206e565b8480fd5b60c43580159081150361222b5799612066565b5063b47b2fb160e01b9650949350505050565b6004356001600160a01b03818116918290036102c057602435908082168092036102c05760443562ffffff81168091036102c057606435908160020b8092036102c0576084359283168093036102c057604051936020850195865260408501526060840152608083015260a082015260a081526122d181611c99565b51902090565b6024356001600160a01b03818116918290036102c057604435908082168092036102c05760643562ffffff81168091036102c057608435908160020b8092036102c05760a4359283168093036102c057604051936020850195865260408501526060840152608083015260a082015260a081526122d181611c9956fea264697066735822122036240c439e054a2d62db11ec63ce0c528819d19cea890dab69bf7ebaaddcaf6164736f6c63430008180033000000000000000000000000000000000004444c5dc75cb358380d2e3de08a90000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000b80c866bb98944e967ac61b6665fbb5225f0d587000000000000000000000000a80a932f626c484898b851e681dbe2c9b279fbed
Deployed Bytecode
0x608080604052600436101561001d575b50361561001b57600080fd5b005b600090813560e01c90816321d0ee7014611a405750806322dcd13e1461152457806322ebb0f814611567578063259982e51461154257806326e3c685146115245780632c597de91461150757806331521d57146105e15780633fc8cef3146114c25780634c1a69001461148d578063575e24b4146114095780635bb47808146113c7578063602cf5731461136a5780636c2bbe7e1461133d5780636fe7e6eb146112ee578063853a65f91461084d5780638d01513c146112d157806391dd734614610b0357806392eefe9b14610abc5780639c6b88a814610a985780639dd58b58146109ea5780639f063efc146109bd578063a97edea81461094b578063ade41d501461091e578063b47b2fb11461089c578063b6a8b0fa14610876578063bb1f60d01461084d578063c45a015514610824578063c4e833ce14610699578063c580c9421461061d578063cb371f83146105ff578063d3631fa5146105e1578063d427ceaa146105b7578063d73792a91461059a578063d89135cd1461057c578063dc4c90d314610537578063dc98354e146104f5578063dd98d7c11461037a578063dfc90cf2146102eb578063e1b4af69146102c5578063eb9912e0146102125763f77c47910361000f573461020f578060031936011261020f57546040516001600160a01b039091168152602090f35b80fd5b503461020f57606036600319011261020f5760243561ffff8082168092036102c05761023c611c59565b83549091906001600160a01b031633036102ae576105dc9081841161029c5782161161029c5760048035845260205260408320805463ffff00001990931663ffffffff199093169290921760109190911b63ffff00001617905580f35b80f35b6040516337d4ed5b60e01b8152600490fd5b6040516323019e6760e01b8152600490fd5b600080fd5b503461020f576102d436611c02565b505050505050602060405163e1b4af6960e01b8152f35b503461020f57602036600319011261020f57610305611a64565b81546001600160a01b039190821633036102ae5781168015610368577fb4e31e50e03f47b5be13be5942bd3a5b1b6048e886cfd1ce1932910251b2958e91604091600154918160018060a01b03198416176001558351921682526020820152a180f35b60405163e6c4247b60e01b8152600490fd5b503461020f5760a036600319011261020f57600435610397611a7a565b61039f611c59565b916064359261ffff8085168095036102c05785546001600160a01b039260843592918416331415806104e7575b6102ae578116916105dc80841161029c57871161029c5780156104d55784885260046020526002604089200154906040519260c08401908482106001600160401b038311176104bf576102999960039661048293604052865260208601908152604086019384526060860194855287608087019a168a5260a086019860018a528c5260046020528160408d2096511661ffff198754161786555116849063ffff000082549160101b169063ffff00001916179055565b516001830155516002820155935193018054925160ff60a01b90151560a01b166001600160a81b03199093169190931660ff60a01b191617179055565b634e487b7160e01b600052604160045260246000fd5b60405163aabd5a0960e01b8152600490fd5b5083600254163314156103cc565b503461020f5760e036600319011261020f5761050f611a64565b5060a036602319011261020f57610524611b9d565b50604051636e4c1aa760e11b8152602090f35b503461020f578060031936011261020f576040517f000000000000000000000000000000000004444c5dc75cb358380d2e3de08a906001600160a01b03168152602090f35b503461020f578060031936011261020f576020600654604051908152f35b503461020f578060031936011261020f5760206040516127108152f35b503461020f57602036600319011261020f5760406020916004358152600983522054604051908152f35b503461020f578060031936011261020f576020600754604051908152f35b503461020f578060031936011261020f576020600554604051908152f35b503461020f57602036600319011261020f578054600435906001600160a01b031633036102ae5761138881116106875760407fb7cf940f291738114d642ccbcbdedeeeddc0bb17e043b90365614d7159129d7191600354908060035582519182526020820152a180f35b60405163183440b760e31b8152600490fd5b503461020f578060031936011261020f57806101c0916101a06040516106be81611c7d565b8281528260208201528260408201528260608201528260808201528260a08201528260c08201528260e0820152826101008201528261012082015282610140820152826101608201528261018082015201526101a060405161071f81611c7d565b8281528260208201528260408201528260608201528260808201528260a0820152600160c0820152600160e082015282610100820152826101208201526001610140820152600161016082015282610180820152828282015260405192835260208101511515602084015260408101511515604084015260608101511515606084015260808101511515608084015260a0810151151560a084015260c0810151151560c084015260e0810151151560e084015261010081015115156101008401526101208101511515610120840152610140810151151561014084015261016081015115156101608401526101808101511515610180840152015115156101a0820152f35b503461020f578060031936011261020f576002546040516001600160a01b039091168152602090f35b503461020f578060031936011261020f576001546040516001600160a01b039091168152602090f35b503461020f5761088536611c02565b5050505050506020604051635b54587d60e11b8152f35b503461020f5761016036600319011261020f576108b7611a64565b5060a036602319011261020f5760603660c319011261020f57610144356001600160401b03811161091a576108f0903690600401611aa4565b5050604061090061012435611fc1565b82516001600160e01b03199092168252600f0b6020820152f35b5080fd5b503461020f57602036600319011261020f5760026040602092600435815260048452200154604051908152f35b503461020f57602036600319011261020f57604060c091600435815260046020522060ff81549161ffff906001810154600360028301549201549260405195818116875260101c1660208601526040850152606084015260018060a01b038116608084015260a01c16151560a0820152f35b503461020f576109cc36611b34565b50505050505050604080516327c18fbf60e21b815260006020820152f35b503461020f578060031936011261020f576040516370a0823160e01b8152306004820152906020826024817f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b03165afa908115610a8c5790610a59575b602090604051908152f35b506020813d602011610a84575b81610a7360209383611cb4565b810103126102c05760209051610a4e565b3d9150610a66565b604051903d90823e3d90fd5b503461020f5760a036600319011261020f576020610ab4612255565b604051908152f35b503461020f57602036600319011261020f57610ad6611a64565b8154906001600160a01b039081831633036102ae5716908115610368576001600160a01b03191617815580f35b503461020f57602036600319011261020f576004356001600160401b03811161091a57610b34903690600401611aa4565b7f000000000000000000000000000000000004444c5dc75cb358380d2e3de08a906001600160a01b0316330361129a57819081010361010081126111555760a01361091a576040519060a082018281106001600160401b0382111761128657604052610b9f81611a90565b91828152610baf60208301611a90565b806020830152604083013562ffffff811681036111d657604083015260608301358060020b81036111d6576060830152610beb60808401611a90565b608083015260c0830135906001600160a01b03821682036111d6576001600160a01b0390811692907f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc21683036112765782945b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b0316840361126f576001600160a01b0316925b60a0850135600160ff1b1461125b577f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b03168114611241576401000276a45b604051908160608101106001600160401b0360608401111761122d57606082810160409081526001600160a01b037f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc28116861415855260a08a01358c0360208087019182529482168387019081528351633cf3645360e21b815289518416600482015289870151841660248201529389015162ffffff1660448501529388015160020b6064840152608090970151811660848301529351151560a4820152945160c486015251821660e485015261012061010485015261012484018990529083906101449082908b907f000000000000000000000000000000000004444c5dc75cb358380d2e3de08a90165af19182156112225787926111ea575b507f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b0316036111e25760801d600f0b5b8581600f0b136000146111da576001600160801b0316935b7f000000000000000000000000000000000004444c5dc75cb358380d2e3de08a906001600160a01b03163b156111d657604051632961046560e21b81526001600160a01b0391821660048201529086908290602490829084907f000000000000000000000000000000000004444c5dc75cb358380d2e3de08a90165af180156111cb576111b6575b5060405163a9059cbb60e01b8082526001600160a01b037f000000000000000000000000000000000004444c5dc75cb358380d2e3de08a9016600483015260a08501356024830152869390929160208180604481010381887f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b03165af1801561118c57611197575b50604051630476982d60e21b8152602081600481887f000000000000000000000000000000000004444c5dc75cb358380d2e3de08a906001600160a01b03165af1801561118c5761115d575b508561102a575b5050505060055460001981146110165760e07f9ff78e7c440e5fcb39d1e846ff16b1e3ab6ba799bf89e6e5b33cab8fe5df891a9260016040930160055582519460a082013586526020860152013592a260405160208101918183106001600160401b038411176104bf5761101292604052815260405191829182611bd6565b0390f35b634e487b7160e01b84526011600452602484fd5b7f000000000000000000000000000000000004444c5dc75cb358380d2e3de08a906001600160a01b03163b1561115957838661107d926040519384928392630b0d9c0960e01b8452309060048501611d48565b0381837f000000000000000000000000000000000004444c5dc75cb358380d2e3de08a906001600160a01b03165af1908115611136578491611141575b505060446020926040519485938492835261dead600484015288602484015260018060a01b03165af1801561113657611107575b506110fb82600654611d0b565b60065582388080610f93565b6111289060203d60201161112f575b6111208183611cb4565b810190611d18565b50386110ee565b503d611116565b6040513d86823e3d90fd5b61114a90611c6a565b6111555782386110ba565b8280fd5b8380fd5b6020809295503d8311611185575b6111758183611cb4565b810103126102c057859238610f8c565b503d61116b565b6040513d87823e3d90fd5b6111af9060203d60201161112f576111208183611cb4565b5038610f40565b6111c39095919295611c6a565b939038610eb1565b6040513d88823e3d90fd5b8580fd5b508493610e29565b600f0b610e11565b9091506020813d60201161121a575b8161120660209383611cb4565b8101031261121657519038610dda565b8680fd5b3d91506111f9565b6040513d89823e3d90fd5b634e487b7160e01b89526041600452602489fd5b73fffd8963efd1fc6a506488495d951d5263988d25610cbf565b634e487b7160e01b87526011600452602487fd5b5082610c79565b6001600160a01b03851694610c3e565b634e487b7160e01b84526041600452602484fd5b60405162461bcd60e51b815260206004820152600f60248201526e2737ba102837b7b626b0b730b3b2b960891b6044820152606490fd5b503461020f578060031936011261020f5760206040516113888152f35b503461020f5761010036600319011261020f57611309611a64565b5060a036602319011261020f5761131e611b9d565b5060e4358060020b0361020f57604051636fe7e6eb60e01b8152602090f35b503461020f5760409061134f36611b34565b50505050505050815190633615df3f60e11b82526020820152f35b503461020f57604036600319011261020f57602435801515810361091a5781546001600160a01b031633036102ae5760048035835260205260408220600301805460ff60a01b191691151560a01b60ff60a01b1691909117905580f35b503461020f57602036600319011261020f576113e1611a64565b81546001600160a01b039190821633036102ae571660018060a01b0319600254161760025580f35b503461020f5761014036600319011261020f57611424611a64565b5060a036602319011261020f5760603660c319011261020f57610124356001600160401b03811161091a5761145d903690600401611aa4565b5050606062ffffff61146d611d6a565b906040939293519363ffffffff60e01b1684526020840152166040820152f35b503461020f57602036600319011261020f57604060209160043581526004835220600160028201549101541115604051908152f35b503461020f578060031936011261020f576040517f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b03168152602090f35b503461020f578060031936011261020f5760206040516105dc8152f35b503461020f578060031936011261020f576020600354604051908152f35b503461020f5761155136611ad1565b5050505050602060405163259982e560e01b8152f35b503461020f5760a036600319011261020f57611581612255565b80825260206004815260408320600381019260ff845460a01c1615611a0d5760028201926001845493015483106119d1576040516370a0823160e01b81523060048201526001600160a01b037f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2811696602496919492909190848189818c5afa9081156119c6578a91611999575b508015611960578681101561195957955b86808211156119505761163291611cd5565b905b5561164f61271061164760035488611cf8565b048096611cd5565b9480151580611943575b611869575b5084611668578780f35b60405163095ea7b360e01b81527f000000000000000000000000000000000004444c5dc75cb358380d2e3de08a906001600160a01b038116600483015260248201879052979091908490839060449082908d905af191821561185e578592611841575b50541660405194846116db611a64565b1684870152846116e9611a7a565b16604087015260443562ffffff811680910361183d5760608701526064358060020b80910361183d57608087015260843585811680910361183d5760a087015260c086015260e08501526101009081850152835261012092838101956001600160401b03938288108589111761182a57889188838193826040526348c8949160e01b835261011f1987611780816101248101611bd6565b030193165af180156112225761179557808780f35b3d8088883e6117a48188611cb4565b81019582828689019803126118265751908382116118265701928561013f8501121561121657830151936101409285116118145750604051946117f0601f8601601f1916830187611cb4565b8486528285850101116111d65761180994019101611bb3565b388080808080808780f35b634e487b7160e01b8752604160045286fd5b8780fd5b634e487b7160e01b895260416004528689fd5b8980fd5b61185790853d871161112f576111208183611cb4565b50386116cb565b6040513d8b823e3d90fd5b6001546040805163a9059cbb60e01b8782019081529288166001600160a01b03168a82019081526020810185905287938d939092916118b39183910103601f198101835282611cb4565b5190828c5af1156119385788513d61192f5750873b155b611917577f57982d28adf5212b25ddfe8de7bc312243fa25e94b54db636b0371290f648fcc6040826118ff8694600754611d0b565b6007558760015416825191825287820152a23861165e565b604051635274afe760e01b8152600481018990528790fd5b600114156118ca565b6040513d8a823e3d90fd5b5084600154161515611659565b50508890611634565b5085611620565b60405162461bcd60e51b8152600481018690526012818a0152714e6f205745544820746f206275796261636b60701b6044820152606490fd5b90508481813d83116119bf575b6119b08183611cb4565b8101031261183d57513861160f565b503d6119a6565b6040513d8c823e3d90fd5b6064906040519062461bcd60e51b825260048201526015602482015274151a1c995cda1bdb19081b9bdd081c995858da1959605a1b6044820152fd5b60405162461bcd60e51b815260048101849052600b60248201526a139bdd08195b98589b195960aa1b6044820152606490fd5b90503461091a57602090611a5336611ad1565b505063021d0ee760e41b8452505050f35b600435906001600160a01b03821682036102c057565b602435906001600160a01b03821682036102c057565b35906001600160a01b03821682036102c057565b9181601f840112156102c0578235916001600160401b0383116102c057602083818601950101116102c057565b906101606003198301126102c0576004356001600160a01b03811681036102c0579160a06023198201126102c057602491608060c3198301126102c05760c49161014435906001600160401b0382116102c057611b3091600401611aa4565b9091565b906101a06003198301126102c0576004356001600160a01b03811681036102c0579160a06023198201126102c057602491608060c3198301126102c05760c4916101443591610164359161018435906001600160401b0382116102c057611b3091600401611aa4565b60c435906001600160a01b03821682036102c057565b60005b838110611bc65750506000910152565b8181015183820152602001611bb6565b60409160208252611bf68151809281602086015260208686019101611bb3565b601f01601f1916010190565b6101206003198201126102c0576004356001600160a01b03811681036102c0579160a06023198301126102c05760249160c4359160e4359161010435906001600160401b0382116102c057611b3091600401611aa4565b6044359061ffff821682036102c057565b6001600160401b0381116104bf57604052565b6101c081019081106001600160401b038211176104bf57604052565b60c081019081106001600160401b038211176104bf57604052565b90601f801991011681019081106001600160401b038211176104bf57604052565b91908203918211611ce257565b634e487b7160e01b600052601160045260246000fd5b81810292918115918404141715611ce257565b91908201809211611ce257565b908160209103126102c0575180151581036102c05790565b600f0b60016001607f1b03198114611ce25760000390565b6001600160a01b03918216815291166020820152604081019190915260600190565b6001600160a01b037f000000000000000000000000000000000004444c5dc75cb358380d2e3de08a9081169033829003611faf57611da66122d7565b9160009280845260046020526040842060ff600382015460a01c1615611f9d5760443592848416808503611216577f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2861614938415611f8d5760c435801590811503611826575b611e26575b506315d7892d60e21b968695509350505050565b61ffff835416958615611f7857612710611e6460e435988a8a12998a600014611f6a576001600160801b0390611e5e90600f0b611d30565b16611cf8565b049586611e72575050611e12565b96989615611f5957505b813b156112165784611ea992889283604051809681958294630b0d9c0960e01b8452309060048501611d48565b03925af180156111cb57611f45575b50600201611ec7838254611d0b565b90557f9cae4344a2aa90b3dbc6528a3f2ffaed048544717fac552b75ee12618278d7076040805184815260016020820152a28315611f3e576001600160801b038116600f0b935b15611f2c575081925b6315d7892d60e21b93600f0b9060801b179190565b6001600160801b0316600f0b92611f17565b8293611f0e565b94611f5260029296611c6a565b9490611eb8565b602435915081168114611e7c578680fd5b6001600160801b0316611cf8565b506315d7892d60e21b97879650945050505050565b60c4358015158114611e0d578780fd5b506315d7892d60e21b94849350915050565b60405163570c108560e11b8152600490fd5b906001600160a01b037f000000000000000000000000000000000004444c5dc75cb358380d2e3de08a90811633819003611faf57611ffd6122d7565b9160009083825260046020526040918281209360ff600386015460a01c161561224257604435838116808203611159577f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc285161493841561222f5760c435801515810361222b57995b849a8061221a575b6120cd575b5050505050506001600283015492015482101561209b575b5063b47b2fb160e01b9392915050565b7fed9753748c66ee1df3e83ee8ba5d83244f01c004097e0e4eebd94e5fd6fea5f19160209151908152a238808061208b565b851561220f57600f0b5b8481600f0b8181136000146121ea5750506001600160801b03165b80156120735761210e6127109161ffff8a5460101c1690611cf8565b0494851561207357909192938095969a50506000146121d957505b813b156111555783612155928492838b51809681958294630b0d9c0960e01b8452309060048501611d48565b03925af180156121cf5785927f9cae4344a2aa90b3dbc6528a3f2ffaed048544717fac552b75ee12618278d7079289926121c0575b506002860161219a868254611d0b565b90558151908582526020820152a26001600160801b0316600f0b93388080808080612073565b6121c990611c6a565b3861218a565b87513d84823e3d90fd5b602435915081168114612129578280fd5b1215612208576001600160801b039061220290611d30565b166120f2565b50836120f2565b60801d600f0b6120d7565b5061ffff885460101c16151561206e565b8480fd5b60c43580159081150361222b5799612066565b5063b47b2fb160e01b9650949350505050565b6004356001600160a01b03818116918290036102c057602435908082168092036102c05760443562ffffff81168091036102c057606435908160020b8092036102c0576084359283168093036102c057604051936020850195865260408501526060840152608083015260a082015260a081526122d181611c99565b51902090565b6024356001600160a01b03818116918290036102c057604435908082168092036102c05760643562ffffff81168091036102c057608435908160020b8092036102c05760a4359283168093036102c057604051936020850195865260408501526060840152608083015260a082015260a081526122d181611c9956fea264697066735822122036240c439e054a2d62db11ec63ce0c528819d19cea890dab69bf7ebaaddcaf6164736f6c63430008180033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000000000000004444c5dc75cb358380d2e3de08a90000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000b80c866bb98944e967ac61b6665fbb5225f0d587000000000000000000000000a80a932f626c484898b851e681dbe2c9b279fbed
-----Decoded View---------------
Arg [0] : _poolManager (address): 0x000000000004444c5dc75cB358380D2e3dE08A90
Arg [1] : _weth (address): 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2
Arg [2] : _controller (address): 0xb80C866bb98944E967aC61b6665FBb5225f0D587
Arg [3] : _platformFeeCollector (address): 0xa80a932F626c484898B851E681dbE2c9B279FBEd
-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 000000000000000000000000000000000004444c5dc75cb358380d2e3de08a90
Arg [1] : 000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2
Arg [2] : 000000000000000000000000b80c866bb98944e967ac61b6665fbb5225f0d587
Arg [3] : 000000000000000000000000a80a932f626c484898b851e681dbe2c9b279fbed
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 36 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|---|---|---|---|---|
| ETH | 100.00% | $3,042.77 | 0.0871 | $265.05 |
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.