Overview
ETH Balance
ETH Value
$0.00Latest 13 from a total of 13 transactions
| Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Transfer Ownersh... | 20001409 | 140 days ago | IN | 0 ETH | 0 | ||||
| Set Surge Fee Mu... | 19964644 | 140 days ago | IN | 0 ETH | 0.00000005 | ||||
| Set Surge Decay ... | 19963816 | 140 days ago | IN | 0 ETH | 0.00000008 | ||||
| Set Max Base Fee | 19963728 | 140 days ago | IN | 0 ETH | 0.00000009 | ||||
| Set Max Base Fee | 19963618 | 140 days ago | IN | 0 ETH | 0.00000009 | ||||
| Set Min Base Fee | 19963550 | 140 days ago | IN | 0 ETH | 0.00000009 | ||||
| Set Base Fee Fac... | 19298797 | 148 days ago | IN | 0 ETH | 0 | ||||
| Set Base Fee Fac... | 19298480 | 148 days ago | IN | 0 ETH | 0 | ||||
| Set Base Fee Fac... | 18926572 | 152 days ago | IN | 0 ETH | 0.00000001 | ||||
| Set Pool POL Sha... | 18817184 | 153 days ago | IN | 0 ETH | 0.00000003 | ||||
| Set Pool POL Sha... | 18815974 | 153 days ago | IN | 0 ETH | 0.00000002 | ||||
| Set Pool POL Sha... | 18739420 | 154 days ago | IN | 0 ETH | 0.00000001 | ||||
| Set Max Base Fee | 18739328 | 154 days ago | IN | 0 ETH | 0.00000001 |
Latest 25 internal transactions (View All)
| Parent Transaction Hash | Block | From | To | ||||
|---|---|---|---|---|---|---|---|
| 32108137 | 1 min ago | 0 ETH | |||||
| 32108137 | 1 min ago | 0 ETH | |||||
| 32108137 | 1 min ago | 0 ETH | |||||
| 32108137 | 1 min ago | 0 ETH | |||||
| 32108137 | 1 min ago | 0 ETH | |||||
| 32108137 | 1 min ago | 0 ETH | |||||
| 32108137 | 1 min ago | 0 ETH | |||||
| 32108099 | 2 mins ago | 0 ETH | |||||
| 32108099 | 2 mins ago | 0 ETH | |||||
| 32108099 | 2 mins ago | 0 ETH | |||||
| 32108099 | 2 mins ago | 0 ETH | |||||
| 32108099 | 2 mins ago | 0 ETH | |||||
| 32108099 | 2 mins ago | 0 ETH | |||||
| 32108094 | 2 mins ago | 0 ETH | |||||
| 32108094 | 2 mins ago | 0 ETH | |||||
| 32108094 | 2 mins ago | 0 ETH | |||||
| 32108094 | 2 mins ago | 0 ETH | |||||
| 32108094 | 2 mins ago | 0 ETH | |||||
| 32108094 | 2 mins ago | 0 ETH | |||||
| 32108075 | 2 mins ago | 0 ETH | |||||
| 32108075 | 2 mins ago | 0 ETH | |||||
| 32108075 | 2 mins ago | 0 ETH | |||||
| 32108075 | 2 mins ago | 0 ETH | |||||
| 32108065 | 2 mins ago | 0 ETH | |||||
| 32108065 | 2 mins ago | 0 ETH |
Cross-Chain Transactions
Contract Source Code Verified (Exact Match)
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.27;
// - - - Solmate Deps - - -
import {Owned} from "solmate/src/auth/Owned.sol";
// - - - V4 Deps - - -
import {PoolId, PoolIdLibrary} from "v4-core/src/types/PoolId.sol";
// - - - Project Deps - - -
import {PrecisionConstants} from "./libraries/PrecisionConstants.sol";
import {Errors} from "./errors/Errors.sol";
import {PolicyManagerErrors} from "./errors/PolicyManagerErrors.sol";
import {IPoolPolicyManager} from "./interfaces/IPoolPolicyManager.sol";
/// @title PoolPolicyManager
/// @notice Consolidated policy manager implementing the IPoolPolicyManager interface
/// @dev Handles all policy functionality for pool configuration and fee management
contract PoolPolicyManager is IPoolPolicyManager, Owned {
// === Constants ===
uint24 private constant MIN_TRADING_FEE = 100; // 0.01%
uint24 private constant MAX_TRADING_FEE = 50_000; // 5%
uint32 private constant DEFAULT_CAP_BUDGET_DECAY_WINDOW = 15_552_000;
uint32 private constant DEFAULT_SURGE_DECAY_PERIOD_SECONDS = 3600;
uint24 private constant DEFAULT_SURGE_FEE_MULTIPLIER_PPM = 3_000_000;
uint24 private constant DEFAULT_MAX_TICKS_PER_BLOCK = 50;
/// @notice Maximum step for base fee updates (10% per step)
uint32 private constant MAX_STEP_PPM = 100_000;
/// @notice Default base fee step size (2% per step)
uint32 private constant DEFAULT_BASE_FEE_STEP_PPM = 20_000;
/// @notice Default base fee update interval (1 day)
uint32 private constant DEFAULT_BASE_FEE_UPDATE_INTERVAL_SECS = 1 days;
/// @notice Default base fee factor (1 tick = 100 PPM)
uint32 private constant DEFAULT_BASE_FEE_FACTOR_PPM = 100;
/// @notice Maximum base fee factor to prevent overflow (1 tick = 1000 PPM max)
uint32 private constant MAX_BASE_FEE_FACTOR_PPM = 1000;
// === Dynamic Fee Configuration Struct ===
struct DynamicFeeConfig {
uint32 capBudgetDecayWindow;
uint24 minBaseFeePpm;
uint24 maxBaseFeePpm;
uint32 surgeDecayPeriodSeconds;
uint24 surgeFeeMultiplierPpm;
}
struct BaseFeeParams {
uint32 stepPpm;
uint32 updateIntervalSecs;
}
// === State Variables ===
/// @notice Manual fee override per pool (if non-zero)
mapping(PoolId => uint24) private _poolManualFee;
/// @notice Flag to indicate if a manual fee is set for a pool
mapping(PoolId => bool) private _hasPoolManualFee;
/// @notice Pool-specific POL share percentages
mapping(PoolId => uint256) private _poolPolSharePpm;
/// @notice Pool-specific dynamic fee configurations
mapping(PoolId => DynamicFeeConfig) private _poolDynamicFeeConfig;
/// @notice Base fee parameters per pool
mapping(PoolId => BaseFeeParams) private _poolBaseFeeParams;
/// @notice Default daily budget for CAP events (ppm/day) 1e6 is 1 per day, 1e7 is 10 per day
uint32 private _defaultCapBudgetDailyPpm;
/// @notice Pool-specific daily budget for CAP events (0 means use default)
mapping(PoolId => uint32) private _poolCapBudgetDailyPpm;
/// @notice Linear decay half-life for the budget counter (seconds)
uint32 private _capBudgetDecayWindow;
/// @notice Pool-specific base fee factor for converting oracle ticks to PPM
mapping(PoolId => uint32) private _poolBaseFeeFactor;
/// @notice Constructor initializes the policy manager with default values
/// @param _governance The owner of the contract
/// @param _dailyBudget Initial daily budget
constructor(address _governance, uint256 _dailyBudget) Owned(_governance) {
if (_governance == address(0)) revert Errors.ZeroAddress();
// Initialize global parameters
_defaultCapBudgetDailyPpm = _dailyBudget == 0 ? 1_000_000 : uint32(_dailyBudget);
_capBudgetDecayWindow = 15_552_000; // 180 days
}
// === Fee Allocation Functions ===
/// @inheritdoc IPoolPolicyManager
function setPoolPOLShare(PoolId poolId, uint256 newPolSharePpm) external override onlyOwner {
// Validate POL share is within valid range (0-100%)
if (newPolSharePpm > PrecisionConstants.PPM_SCALE) {
revert Errors.ParameterOutOfRange(newPolSharePpm, 0, PrecisionConstants.PPM_SCALE);
}
uint256 oldShare = _poolPolSharePpm[poolId];
if (oldShare != newPolSharePpm) {
_poolPolSharePpm[poolId] = newPolSharePpm;
emit PoolPOLShareChanged(poolId, newPolSharePpm);
}
}
/// @inheritdoc IPoolPolicyManager
function getPoolPOLShare(PoolId poolId) external view override returns (uint256 poolSpecificPolShare) {
poolSpecificPolShare = _poolPolSharePpm[poolId];
}
// === Manual Fee Override Functions ===
/// @inheritdoc IPoolPolicyManager
function getManualFee(PoolId poolId) external view override returns (uint24 manualFee, bool isSet) {
return (_poolManualFee[poolId], _hasPoolManualFee[poolId]);
}
/// @inheritdoc IPoolPolicyManager
function setManualFee(PoolId poolId, uint24 manualFee) external override onlyOwner {
if (manualFee < MIN_TRADING_FEE || manualFee > MAX_TRADING_FEE) {
revert Errors.ParameterOutOfRange(manualFee, MIN_TRADING_FEE, MAX_TRADING_FEE);
}
_poolManualFee[poolId] = manualFee;
_hasPoolManualFee[poolId] = true;
emit ManualFeeSet(poolId, manualFee);
}
/// @inheritdoc IPoolPolicyManager
function clearManualFee(PoolId poolId) external override onlyOwner {
if (_hasPoolManualFee[poolId]) {
_poolManualFee[poolId] = 0;
_hasPoolManualFee[poolId] = false;
emit ManualFeeSet(poolId, 0);
}
}
// === Dynamic Fee Configuration Getters ===
/// @inheritdoc IPoolPolicyManager
function getMinBaseFee(PoolId poolId) external view override returns (uint24) {
if (_poolDynamicFeeConfig[poolId].minBaseFeePpm != 0) {
return _poolDynamicFeeConfig[poolId].minBaseFeePpm;
}
return MIN_TRADING_FEE;
}
/// @inheritdoc IPoolPolicyManager
function getMaxBaseFee(PoolId poolId) external view override returns (uint24) {
if (_poolDynamicFeeConfig[poolId].maxBaseFeePpm != 0) {
return _poolDynamicFeeConfig[poolId].maxBaseFeePpm;
}
return MAX_TRADING_FEE;
}
/// @inheritdoc IPoolPolicyManager
function getSurgeDecayPeriodSeconds(PoolId poolId) external view override returns (uint32) {
if (_poolDynamicFeeConfig[poolId].surgeDecayPeriodSeconds != 0) {
return _poolDynamicFeeConfig[poolId].surgeDecayPeriodSeconds;
}
return DEFAULT_SURGE_DECAY_PERIOD_SECONDS;
}
/// @inheritdoc IPoolPolicyManager
function getSurgeFeeMultiplierPpm(PoolId poolId) external view override returns (uint24) {
if (_poolDynamicFeeConfig[poolId].surgeFeeMultiplierPpm != 0) {
return _poolDynamicFeeConfig[poolId].surgeFeeMultiplierPpm;
}
return DEFAULT_SURGE_FEE_MULTIPLIER_PPM;
}
/// @inheritdoc IPoolPolicyManager
function getDefaultDailyBudgetPpm() external view override returns (uint32) {
return _defaultCapBudgetDailyPpm;
}
/// @inheritdoc IPoolPolicyManager
function getDailyBudgetPpm(PoolId poolId) external view override returns (uint32) {
uint32 poolBudget = _poolCapBudgetDailyPpm[poolId];
return poolBudget == 0 ? _defaultCapBudgetDailyPpm : poolBudget;
}
/// @inheritdoc IPoolPolicyManager
function getCapBudgetDecayWindow(PoolId poolId) external view override returns (uint32) {
if (_poolDynamicFeeConfig[poolId].capBudgetDecayWindow != 0) {
return _poolDynamicFeeConfig[poolId].capBudgetDecayWindow;
}
return _capBudgetDecayWindow;
}
/// @inheritdoc IPoolPolicyManager
function getDefaultMaxTicksPerBlock(PoolId) external pure override returns (uint24) {
return DEFAULT_MAX_TICKS_PER_BLOCK;
}
/// @inheritdoc IPoolPolicyManager
function getBaseFeeStepPpm(PoolId poolId) public view override returns (uint32) {
uint32 val = _poolBaseFeeParams[poolId].stepPpm;
return val == 0 ? DEFAULT_BASE_FEE_STEP_PPM : val;
}
/// @inheritdoc IPoolPolicyManager
function getBaseFeeUpdateIntervalSeconds(PoolId poolId) public view override returns (uint32) {
uint32 val = _poolBaseFeeParams[poolId].updateIntervalSecs;
return val == 0 ? DEFAULT_BASE_FEE_UPDATE_INTERVAL_SECS : val;
}
/// @inheritdoc IPoolPolicyManager
function getBaseFeeFactor(PoolId poolId) external view override returns (uint32) {
uint32 factor = _poolBaseFeeFactor[poolId];
return factor == 0 ? DEFAULT_BASE_FEE_FACTOR_PPM : factor;
}
// === Dynamic Fee Configuration Setters ===
/// @inheritdoc IPoolPolicyManager
function setMinBaseFee(PoolId poolId, uint24 newMinFee) external override onlyOwner {
uint24 maxFee = this.getMaxBaseFee(poolId);
if (newMinFee < MIN_TRADING_FEE || newMinFee > maxFee) {
revert PolicyManagerErrors.InvalidFeeRange(newMinFee, MIN_TRADING_FEE, maxFee);
}
_poolDynamicFeeConfig[poolId].minBaseFeePpm = newMinFee;
emit MinBaseFeeSet(poolId, newMinFee);
}
/// @inheritdoc IPoolPolicyManager
function setMaxBaseFee(PoolId poolId, uint24 newMaxFee) external override onlyOwner {
uint24 minFee = this.getMinBaseFee(poolId);
if (newMaxFee < minFee || newMaxFee > MAX_TRADING_FEE) {
revert PolicyManagerErrors.InvalidFeeRange(newMaxFee, minFee, MAX_TRADING_FEE);
}
_poolDynamicFeeConfig[poolId].maxBaseFeePpm = newMaxFee;
emit MaxBaseFeeSet(poolId, newMaxFee);
}
/// @inheritdoc IPoolPolicyManager
function setCapBudgetDecayWindow(PoolId poolId, uint32 newCapBudgetDecayWindow) external override onlyOwner {
if (newCapBudgetDecayWindow == 0 || newCapBudgetDecayWindow > type(uint32).max) {
revert Errors.ParameterOutOfRange(newCapBudgetDecayWindow, 1, type(uint32).max);
}
_poolDynamicFeeConfig[poolId].capBudgetDecayWindow = newCapBudgetDecayWindow;
emit CapBudgetDecayWindowSet(poolId, newCapBudgetDecayWindow);
}
/// @inheritdoc IPoolPolicyManager
function setSurgeDecayPeriodSeconds(PoolId poolId, uint32 newSurgeDecayPeriodSeconds) external override onlyOwner {
if (newSurgeDecayPeriodSeconds < 60 || newSurgeDecayPeriodSeconds > 1 days) {
revert Errors.ParameterOutOfRange(newSurgeDecayPeriodSeconds, 60, 1 days);
}
_poolDynamicFeeConfig[poolId].surgeDecayPeriodSeconds = newSurgeDecayPeriodSeconds;
emit SurgeDecayPeriodSet(poolId, newSurgeDecayPeriodSeconds);
}
/// @inheritdoc IPoolPolicyManager
function setSurgeFeeMultiplierPpm(PoolId poolId, uint24 multiplier) external override onlyOwner {
if (multiplier == 0 || multiplier > 3_000_000) revert Errors.ParameterOutOfRange(multiplier, 1, 3_000_000);
_poolDynamicFeeConfig[poolId].surgeFeeMultiplierPpm = multiplier;
emit SurgeFeeMultiplierSet(poolId, multiplier);
}
/// @inheritdoc IPoolPolicyManager
function setBaseFeeParams(PoolId poolId, uint32 stepPpm, uint32 updateIntervalSecs) external override onlyOwner {
if (stepPpm > MAX_STEP_PPM) revert Errors.ParameterOutOfRange(stepPpm, 0, MAX_STEP_PPM);
if (updateIntervalSecs == 0) {
revert Errors.ParameterOutOfRange(updateIntervalSecs, 1, type(uint32).max);
}
_poolBaseFeeParams[poolId] = BaseFeeParams({stepPpm: stepPpm, updateIntervalSecs: updateIntervalSecs});
emit BaseFeeParamsSet(poolId, stepPpm, updateIntervalSecs);
}
/// @inheritdoc IPoolPolicyManager
function setDailyBudgetPpm(uint32 newCapBudgetDailyPpm) external override onlyOwner {
if (newCapBudgetDailyPpm == 0 || newCapBudgetDailyPpm > 10 * PrecisionConstants.PPM_SCALE) {
revert Errors.ParameterOutOfRange(newCapBudgetDailyPpm, 1, 10 * PrecisionConstants.PPM_SCALE);
}
_defaultCapBudgetDailyPpm = newCapBudgetDailyPpm;
emit DailyBudgetSet(newCapBudgetDailyPpm);
}
/// @inheritdoc IPoolPolicyManager
function setPoolDailyBudgetPpm(PoolId poolId, uint32 newBudget) external override onlyOwner {
// Validate: 0 means "use default", or 1 to 10*PPM_SCALE
if (newBudget != 0 && (newBudget < 1 || newBudget > 10 * PrecisionConstants.PPM_SCALE)) {
revert Errors.ParameterOutOfRange(newBudget, 1, 10 * PrecisionConstants.PPM_SCALE);
}
_poolCapBudgetDailyPpm[poolId] = newBudget;
emit PoolDailyBudgetSet(poolId, newBudget);
}
/// @inheritdoc IPoolPolicyManager
function setDecayWindow(uint32 newCapBudgetDecayWindow) external override onlyOwner {
if (newCapBudgetDecayWindow == 0) revert PolicyManagerErrors.ZeroValue();
_capBudgetDecayWindow = newCapBudgetDecayWindow;
emit GlobalDecayWindowSet(newCapBudgetDecayWindow);
}
/// @inheritdoc IPoolPolicyManager
function setBaseFeeFactor(PoolId poolId, uint32 factor) external override onlyOwner {
// Validate factor is reasonable (0 means use default)
if (factor != 0 && (factor < 1 || factor > MAX_BASE_FEE_FACTOR_PPM)) {
revert Errors.ParameterOutOfRange(factor, 1, MAX_BASE_FEE_FACTOR_PPM);
}
_poolBaseFeeFactor[poolId] = factor;
emit BaseFeeFactorSet(poolId, factor);
}
}// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
/// @notice Simple single owner authorization mixin.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/auth/Owned.sol)
abstract contract Owned {
/*//////////////////////////////////////////////////////////////
EVENTS
//////////////////////////////////////////////////////////////*/
event OwnershipTransferred(address indexed user, address indexed newOwner);
/*//////////////////////////////////////////////////////////////
OWNERSHIP STORAGE
//////////////////////////////////////////////////////////////*/
address public owner;
modifier onlyOwner() virtual {
require(msg.sender == owner, "UNAUTHORIZED");
_;
}
/*//////////////////////////////////////////////////////////////
CONSTRUCTOR
//////////////////////////////////////////////////////////////*/
constructor(address _owner) {
owner = _owner;
emit OwnershipTransferred(address(0), _owner);
}
/*//////////////////////////////////////////////////////////////
OWNERSHIP LOGIC
//////////////////////////////////////////////////////////////*/
function transferOwnership(address newOwner) public virtual onlyOwner {
owner = newOwner;
emit OwnershipTransferred(msg.sender, newOwner);
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {PoolKey} from "./PoolKey.sol";
type PoolId is bytes32;
/// @notice Library for computing the ID of a pool
library PoolIdLibrary {
/// @notice Returns value equal to keccak256(abi.encode(poolKey))
function toId(PoolKey memory poolKey) internal pure returns (PoolId poolId) {
assembly ("memory-safe") {
// 0xa0 represents the total size of the poolKey struct (5 slots of 32 bytes)
poolId := keccak256(poolKey, 0xa0)
}
}
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.27;
/// @title PrecisionConstants
/// @notice Centralized library for precision-related constants used throughout the protocol
/// @dev This ensures consistency in scaling factors across all contracts
library PrecisionConstants {
/// @notice Standard high-precision scaling factor (10^18)
/// @dev Used for interest rates, LTV ratios, and other high-precision calculations
uint256 internal constant PRECISION = 1e18;
/// @notice Parts-per-million scaling factor (10^6)
/// @dev Used for fee percentages, allocation shares, and other percentage-based calculations
uint256 internal constant PPM_SCALE = 1e6;
}// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0;
import {PoolId} from "v4-core/src/types/PoolId.sol";
// TODO: cleanup unused errors
/**
* @title Errors
* @notice Collection of all custom errors used in the protocol
*/
library Errors {
// --- Access Control ---
error AccessDenied();
error AccessOnlyGovernance(address caller);
error AccessOnlyPoolManager(address caller);
error AccessNotAuthorized(address caller);
error AccessOnlyEmergencyAdmin(address caller);
error Unauthorized();
error CallerNotPoolManager(address caller);
error CallerNotMarginContract();
error AccessOnlyOwner(address caller);
error UnauthorizedCaller(address caller);
error GovernanceNotInitialized();
error HookAddressAlreadySet();
error InvalidHookAddress();
error ZeroDestination();
error NotPoolManager();
// --- Validation & Input ---
error InvalidHookAuthorization(address expected, address actual);
error PoolPositionManagerMismatch();
error ValidationDeadlinePassed(uint32 deadline, uint32 blockTime);
error ValidationZeroAddress(string target);
error ValidationInvalidInput(string reason);
error ValidationZeroAmount(string parameter);
error ValidationInvalidLength(string parameter);
error ValidationInvalidAddress(address target);
error ValidationInvalidRange(string parameter);
error ValidationInvalidFee(uint24 fee);
error ValidationInvalidTickSpacing(int24 tickSpacing);
error ValidationInvalidTick(int24 tick);
error ValidationInvalidSlippage(uint256 slippage);
error ParameterOutOfRange(uint256 value, uint256 min, uint256 max);
error DeadlinePassed(uint32 deadline, uint32 blockTime);
error ArrayLengthMismatch();
error InvalidCallbackSalt();
error InvalidPolicyImplementationsLength(uint256 length);
error NotInitialized();
error AlreadyInitialized(string component);
error ReinvestmentDisabled();
error RateLimited();
error InvalidPoolKey();
error InvalidPoolId();
error InvalidTwapPeriod();
error InvalidTickTolerance();
error ZeroAddress();
error ZeroAmount();
error ZeroLiquidity();
error ZeroShares();
error ZeroPolicyManagerAddress();
error ZeroPoolManagerAddress();
error ZeroFullRangeAddress();
error InvalidCallbackType(uint8 callbackType);
error InvalidTickRange();
error InvalidParameter(string parameterName, uint256 value);
error ExpiryTooSoon(uint256 expiry, uint256 requiredTime);
error ExpiryTooFar(uint256 expiry, uint256 requiredTime);
// --- Math & Calculation ---
error DivisionByZero();
error Overflow();
error Underflow();
error InvalidCalculation();
error InvalidConversion();
error InvalidRatio();
error InvalidAmount();
error InvalidShare();
error InvalidPercentage();
error InvalidFee();
error InvalidPrice(uint160 sqrtPriceX96);
error InvalidLiquidity();
error InvalidInput();
error StaleOracle();
error FeeTooHigh();
error AmountTooLarge(uint256 amount, uint256 maximum);
error SlippageExceeded(uint256 required, uint256 actual);
error CalculationError(string reason);
error MathOverflow();
error MathUnderflow();
error InsufficientInitialLiquidity();
// --- System & State ---
error HookDispatchFailed(bytes4 selector);
error DelegateCallFailed();
error NotImplemented();
error ContractPaused();
error InternalError(string message);
error InconsistentState(string reason);
// --- Pool State & Operations ---
error PoolNotInitialized(bytes32 poolId);
error PoolAlreadyInitialized(bytes32 poolId);
error PoolNotFound(PoolId poolId);
error PoolPaused(bytes32 poolId);
error PoolLocked(bytes32 poolId);
error PoolInvalidState(bytes32 poolId);
error PoolInvalidOperation(bytes32 poolId);
error PoolInvalidParameter(bytes32 poolId);
error PoolUnsupportedFee(uint24 fee);
error PoolUnsupportedTickSpacing(int24 tickSpacing);
error PoolInvalidFeeOrTickSpacing(uint24 fee, int24 tickSpacing);
error PoolTickOutOfRange(int24 tick, int24 minTick, int24 maxTick);
error PoolInEmergencyState(bytes32 poolId);
error PoolInvalidStateTransition(bytes32 poolId, string currentState, string targetState);
error OnlyDynamicFeePoolAllowed();
error FailedToReadPoolData(PoolId poolId);
error PoolKeyAlreadyStored(bytes32 poolId);
// --- Liquidity & Shares ---
error PositionNotFound(PoolId poolId);
error InsufficientAmount(uint256 requested, uint256 available);
error InsufficientLiquidity(uint256 requested, uint256 available);
error InsufficientShares(uint256 requested, uint256 available);
error InsufficientBalance(uint256 requested, uint256 available);
error InsufficientAllowance(uint256 requested, uint256 available);
error LiquidityOverflow();
error LiquidityUnderflow();
error LiquidityLocked();
error LiquidityRangeTooWide();
error LiquidityRangeTooNarrow();
error LiquidityAlreadyExists();
error LiquidityDoesNotExist();
error LiquidityNotAvailable();
error DepositTooSmall();
error InitialDepositTooSmall(uint256 minAmount, uint256 actualAmount);
error WithdrawAmountTooSmall();
// --- Policy ---
error PolicyNotFound();
error PolicyAlreadyExists();
error PolicyInvalidState();
error PolicyInvalidParameter();
error PolicyInvalidOperation();
error PolicyUnauthorized();
error PolicyLocked();
error PolicyExpired();
error PolicyNotActive();
error PolicyNotImplemented();
error AllocationSumError(uint256 polShare, uint256 expected);
// --- Hooks ---
error HookNotFound();
error HookAlreadyExists();
error HookInvalidState();
error HookInvalidParameter();
error HookInvalidOperation();
error HookUnauthorized();
error HookLocked();
error HookExpired();
error HookNotActive();
error HookNotImplemented();
error HookInvalidAddress(address hook);
error HookOnlyInitialization();
error HookOnlyModifyLiquidity();
error HookOnlySwap();
error HookOnlyDonate();
error HookNotSet();
// --- Token & ETH Transfers ---
error TokenNotFound();
error TokenAlreadyExists();
error TokenInvalidState();
error TokenInvalidParameter();
error TokenInvalidOperation();
error TokenUnauthorized();
error TokenLocked();
error TokenExpired();
error TokenNotActive();
error TokenNotImplemented();
error TokenTransferFailed();
error TokenApprovalFailed();
error TokenEthNotAccepted();
error TokenInsufficientEth(uint256 required, uint256 provided);
error TokenEthTransferFailed(address to, uint256 amount);
error NonzeroNativeValue();
error InsufficientETH(uint256 required, uint256 provided);
error InsufficientContractBalance(uint256 required, uint256 available);
error ETHTransferFailed();
error TransferFailed();
error TransferFromFailed();
error InsufficientReserves();
error TooLittleAmount0(uint256 min, uint256 actual);
error TooLittleAmount1(uint256 min, uint256 actual);
// --- Oracle ---
error OracleOperationFailed(string operation, string reason);
error OracleNotInitialized(PoolId poolId);
error OracleUpdateFailed(PoolId poolId, string reason);
error OraclePriceInvalid(uint160 sqrtPriceX96);
error OracleTickInvalid(int24 tick);
error OracleCapExceeded(PoolId poolId, int24 tick, int24 maxMove);
// --- Fee Reinvestment ---
error FeeExtractionFailed(string reason);
error InvalidPolPercentage(uint256 provided, uint256 min, uint256 max);
error PoolSpecificPolPercentageNotAllowed();
error InvalidFeeDistribution(uint256 polShare, uint256 lpShare, uint256 expected);
error PoolReinvestmentBlocked(PoolId poolId);
error CollectionIntervalTooShort(uint256 provided, uint256 minimum);
error CollectionIntervalTooLong(uint256 provided, uint256 maximum);
error HookCallbackFailed(string reason);
error FeesNotAvailable();
error ExtractionAmountExceedsFees();
error CacheStale(uint32 lastUpdate, uint32 currentTime, uint32 maxAge);
error FeeReinvestNotAuthorized(address caller);
error CannotWithdrawProtocolFees();
error ReinvestmentAmountTooSmall(uint256 amount0, uint256 amount1);
error ReinvestmentCooldownNotMet(uint64 lastReinvest, uint64 cooldown);
error ReinvestmentThresholdNotMet(uint256 balance0, uint256 balance1, uint256 min0, uint256 min1);
// --- Margin & Vault ---
error WithdrawalWouldMakeVaultInsolvent();
error NoDebtToRepay();
error DepositFailed();
error InsufficientCollateral(uint256 debt, uint256 collateral, uint256 threshold);
error PoolUtilizationTooHigh();
error InsufficientPhysicalShares(uint256 requested, uint256 available);
error InterestModelNotSet();
error MarginContractNotSet();
error RepayAmountExceedsDebt(uint256 sharesToRepay, uint256 currentDebtShares);
error DepositForRepayFailed();
error InvalidAsset();
error MaxPoolUtilizationExceeded(uint256 currentUtilization, uint256 maxUtilization);
// --- Liquidation ---
error NotLiquidatable(uint256 currentRatio, uint256 threshold);
error LiquidationTooSmall(uint256 requestedAmount, uint256 minimumAmount);
error InvalidLiquidationParams();
// --- Invariants ---
error InvalidSwapDelta();
error ETHRefundFailed();
error InvariantETHTransferFailed();
}// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0;
import {PoolId, PoolIdLibrary} from "v4-core/src/types/PoolId.sol";
/**
* @title Errors
* @notice Custom errors used throughout the Spot system
*/
library PolicyManagerErrors {
// === General errors ===
error ZeroAddress();
error UnauthorizedCaller(address caller);
error ETHRefundFailed();
error ParameterOutOfRange(uint256 value, uint256 min, uint256 max);
error AllocationSumError(uint256 pol, uint256 fullRange, uint256 lp, uint256 expected);
error InvalidFeeRange(uint24 value, uint24 min, uint24 max);
error ZeroValue();
// === Pool-specific errors ===
error PoolNotFound(PoolId poolId);
error PositionNotFound(PoolId poolId);
error PoolPositionManagerMismatch();
error InvalidHookAuthorization(address expected, address actual);
// === Liquidity operations errors ===
error TooLittleAmount0(uint256 minimum, uint256 actual);
error TooLittleAmount1(uint256 minimum, uint256 actual);
error InsufficientETH(uint256 required, uint256 provided);
error InvalidPrice(uint160 price);
error InvalidSwapDelta();
// === Manual fee errors ===
error ManualFeeNotSet(PoolId poolId);
error ManualFeeAlreadySet(PoolId poolId);
}// SPDX-License-Identifier: MIT
pragma solidity >=0.5.0;
import {PoolId} from "v4-core/src/types/PoolId.sol";
/// @title IPoolPolicyManager
/// @notice Consolidated interface for all policy types in the Spot system
/// @dev Combines fee, tick scaling, v-tier, and various other policies into a single interface
interface IPoolPolicyManager {
/// === Events ===
/// @notice Emitted when a pool's POL share is changed
/// @param poolId The ID of the pool
/// @param polSharePpm The new POL share in PPM
event PoolPOLShareChanged(PoolId indexed poolId, uint256 polSharePpm);
/// @notice Emitted when the daily budget is set
/// @param newBudget The new daily budget
event DailyBudgetSet(uint32 newBudget);
/// @notice Emitted when a pool-specific daily budget is set
/// @param poolId The pool ID
/// @param newBudget The new daily budget
event PoolDailyBudgetSet(PoolId indexed poolId, uint32 newBudget);
/// @notice Emitted when base fee parameters are set
/// @param poolId The ID of the pool
/// @param stepPpm The step size in PPM
/// @param updateIntervalSecs The update interval in seconds
event BaseFeeParamsSet(PoolId indexed poolId, uint32 stepPpm, uint32 updateIntervalSecs);
/// @notice Emitted when a manual fee is set for a pool
/// @param poolId The ID of the pool
/// @param manualFee The manual fee in PPM
event ManualFeeSet(PoolId indexed poolId, uint24 manualFee);
/// @notice Emitted when the minimum base fee is set for a pool
/// @param poolId The ID of the pool
/// @param minBaseFeePpm The new minimum base fee in PPM
event MinBaseFeeSet(PoolId indexed poolId, uint24 minBaseFeePpm);
/// @notice Emitted when the maximum base fee is set for a pool
/// @param poolId The ID of the pool
/// @param maxBaseFeePpm The new maximum base fee in PPM
event MaxBaseFeeSet(PoolId indexed poolId, uint24 maxBaseFeePpm);
/// @notice Emitted when the cap budget decay window is set for a pool
/// @param poolId The ID of the pool
/// @param decayWindow The new decay window in seconds
event CapBudgetDecayWindowSet(PoolId indexed poolId, uint32 decayWindow);
/// @notice Emitted when the surge decay period is set for a pool
/// @param poolId The ID of the pool
/// @param decayPeriod The new decay period in seconds
event SurgeDecayPeriodSet(PoolId indexed poolId, uint32 decayPeriod);
/// @notice Emitted when the surge fee multiplier is set for a pool
/// @param poolId The ID of the pool
/// @param multiplier The new multiplier in PPM
event SurgeFeeMultiplierSet(PoolId indexed poolId, uint24 multiplier);
/// @notice Emitted when the global decay window is set
/// @param decayWindow The new decay window in seconds
event GlobalDecayWindowSet(uint32 decayWindow);
/// @notice Emitted when the base fee factor is set for a pool
/// @param poolId The pool ID
/// @param factor The new base fee factor
event BaseFeeFactorSet(PoolId indexed poolId, uint32 factor);
/// === Fee Configuration Functions ===
/// @notice Sets the POL share percentage for a specific pool
/// @param poolId The pool ID
/// @param polSharePpm The POL share in PPM (parts per million)
function setPoolPOLShare(PoolId poolId, uint256 polSharePpm) external;
/// @notice Gets the POL share percentage for a specific pool
/// @param poolId The pool ID to get the POL share for
/// @return The POL share in PPM (parts per million)
function getPoolPOLShare(PoolId poolId) external view returns (uint256);
/// === Manual Fee Functions ===
/// @notice Gets the manual fee for a pool, if set
/// @param poolId The pool ID to get the manual fee for
/// @return manualFee The manual fee in PPM, 0 if not set
/// @return isSet Whether a manual fee is set for this pool
function getManualFee(PoolId poolId) external view returns (uint24 manualFee, bool isSet);
/// @notice Sets a manual fee for a pool, overriding the dynamic fee calculation
/// @param poolId The pool ID
/// @param manualFee The manual fee in PPM
function setManualFee(PoolId poolId, uint24 manualFee) external;
/// @notice Clears a manual fee for a pool, reverting to dynamic fee calculation
/// @param poolId The pool ID
function clearManualFee(PoolId poolId) external;
/// === Dynamic Fee Configuration Functions ===
/// @notice Returns the surge decay period in seconds for the given pool
/// @param poolId The pool ID
/// @return Surge decay period in seconds
function getSurgeDecayPeriodSeconds(PoolId poolId) external view returns (uint32);
/// @notice Gets the default/global/fallback daily budget for CAP events
/// @return The default daily budget in PPM
function getDefaultDailyBudgetPpm() external view returns (uint32);
/// @notice Returns the daily budget for CAP events in PPM for the given pool
/// @param poolId The pool ID
/// @return Daily budget in PPM
function getDailyBudgetPpm(PoolId poolId) external view returns (uint32);
/// @notice Returns the budget decay window in seconds for the given pool
/// @param poolId The pool ID
/// @return Budget decay window in seconds
function getCapBudgetDecayWindow(PoolId poolId) external view returns (uint32);
/// @notice Returns the minimum base fee in PPM for the given pool
/// @param poolId The pool ID
/// @return Minimum base fee in PPM
function getMinBaseFee(PoolId poolId) external view returns (uint24);
/// @notice Returns the maximum base fee in PPM for the given pool
/// @param poolId The pool ID
/// @return Maximum base fee in PPM
function getMaxBaseFee(PoolId poolId) external view returns (uint24);
/// @notice Returns the surge fee multiplier in PPM for the given pool
/// @param poolId The pool ID
/// @return Surge fee multiplier in PPM
function getSurgeFeeMultiplierPpm(PoolId poolId) external view returns (uint24);
/// @notice Returns the default maximum ticks per block for a pool
/// @param poolId The pool ID
/// @return Default maximum ticks per block
function getDefaultMaxTicksPerBlock(PoolId poolId) external view returns (uint24);
/// @notice Returns the base fee step size in PPM for the given pool
/// @param poolId The pool ID
/// @return Base fee step size in PPM
function getBaseFeeStepPpm(PoolId poolId) external view returns (uint32);
/// @notice Returns the base fee update interval in seconds for the given pool
/// @param poolId The pool ID
/// @return Base fee update interval in seconds
function getBaseFeeUpdateIntervalSeconds(PoolId poolId) external view returns (uint32);
/// @notice Gets the base fee factor for converting oracle ticks to fee PPM
/// @param poolId The pool ID
function getBaseFeeFactor(PoolId poolId) external view returns (uint32);
/// === Dynamic Fee Setter Functions ===
/// @notice Sets the cap budget decay window for a pool
/// @param poolId The pool ID
/// @param decayWindow The decay window in seconds
function setCapBudgetDecayWindow(PoolId poolId, uint32 decayWindow) external;
/// @notice Sets the minimum base fee for a pool
/// @param poolId The pool ID
/// @param minBaseFee The minimum base fee in PPM
function setMinBaseFee(PoolId poolId, uint24 minBaseFee) external;
/// @notice Sets the maximum base fee for a pool
/// @param poolId The pool ID
/// @param maxBaseFee The maximum base fee in PPM
function setMaxBaseFee(PoolId poolId, uint24 maxBaseFee) external;
/// @notice Sets the surge decay period in seconds for a pool
/// @param poolId The pool ID
/// @param surgeDecaySeconds The surge decay period in seconds
function setSurgeDecayPeriodSeconds(PoolId poolId, uint32 surgeDecaySeconds) external;
/// @notice Sets the surge fee multiplier for a pool
/// @param poolId The pool ID
/// @param multiplier The surge fee multiplier in PPM
function setSurgeFeeMultiplierPpm(PoolId poolId, uint24 multiplier) external;
/// @notice Sets base fee parameters for a pool
/// @param poolId The pool ID
/// @param stepPpm The step size in PPM
/// @param updateIntervalSecs The update interval in seconds
function setBaseFeeParams(PoolId poolId, uint32 stepPpm, uint32 updateIntervalSecs) external;
/// @notice Sets the daily budget in PPM
/// @param ppm The daily budget in PPM
function setDailyBudgetPpm(uint32 ppm) external;
/// @notice Sets the daily budget for CAP events for a specific pool
/// @param poolId The pool ID
/// @param newBudget The new daily budget in PPM (0 means use default)
function setPoolDailyBudgetPpm(PoolId poolId, uint32 newBudget) external;
/// @notice Sets the decay window in seconds
/// @param secs The decay window in seconds
function setDecayWindow(uint32 secs) external;
/// @notice Sets the base fee factor for a specific pool
/// @param poolId The pool ID
/// @param factor The new base fee factor (1 tick = X PPM)
function setBaseFeeFactor(PoolId poolId, uint32 factor) external;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {Currency} from "./Currency.sol";
import {IHooks} from "../interfaces/IHooks.sol";
import {PoolIdLibrary} from "./PoolId.sol";
using PoolIdLibrary for PoolKey global;
/// @notice Returns the key for identifying a pool
struct PoolKey {
/// @notice The lower currency of the pool, sorted numerically
Currency currency0;
/// @notice The higher currency of the pool, sorted numerically
Currency currency1;
/// @notice The pool LP fee, capped at 1_000_000. If the highest bit is 1, the pool has a dynamic fee and must be exactly equal to 0x800000
uint24 fee;
/// @notice Ticks that involve positions must be a multiple of tick spacing
int24 tickSpacing;
/// @notice The hooks of the pool
IHooks hooks;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {IERC20Minimal} from "../interfaces/external/IERC20Minimal.sol";
import {CustomRevert} from "../libraries/CustomRevert.sol";
type Currency is address;
using {greaterThan as >, lessThan as <, greaterThanOrEqualTo as >=, equals as ==} for Currency global;
using CurrencyLibrary for Currency global;
function equals(Currency currency, Currency other) pure returns (bool) {
return Currency.unwrap(currency) == Currency.unwrap(other);
}
function greaterThan(Currency currency, Currency other) pure returns (bool) {
return Currency.unwrap(currency) > Currency.unwrap(other);
}
function lessThan(Currency currency, Currency other) pure returns (bool) {
return Currency.unwrap(currency) < Currency.unwrap(other);
}
function greaterThanOrEqualTo(Currency currency, Currency other) pure returns (bool) {
return Currency.unwrap(currency) >= Currency.unwrap(other);
}
/// @title CurrencyLibrary
/// @dev This library allows for transferring and holding native tokens and ERC20 tokens
library CurrencyLibrary {
/// @notice Additional context for ERC-7751 wrapped error when a native transfer fails
error NativeTransferFailed();
/// @notice Additional context for ERC-7751 wrapped error when an ERC20 transfer fails
error ERC20TransferFailed();
/// @notice A constant to represent the native currency
Currency public constant ADDRESS_ZERO = Currency.wrap(address(0));
function transfer(Currency currency, address to, uint256 amount) internal {
// altered from https://github.com/transmissions11/solmate/blob/44a9963d4c78111f77caa0e65d677b8b46d6f2e6/src/utils/SafeTransferLib.sol
// modified custom error selectors
bool success;
if (currency.isAddressZero()) {
assembly ("memory-safe") {
// Transfer the ETH and revert if it fails.
success := call(gas(), to, amount, 0, 0, 0, 0)
}
// revert with NativeTransferFailed, containing the bubbled up error as an argument
if (!success) {
CustomRevert.bubbleUpAndRevertWith(to, bytes4(0), NativeTransferFailed.selector);
}
} else {
assembly ("memory-safe") {
// Get a pointer to some free memory.
let fmp := mload(0x40)
// Write the abi-encoded calldata into memory, beginning with the function selector.
mstore(fmp, 0xa9059cbb00000000000000000000000000000000000000000000000000000000)
mstore(add(fmp, 4), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "to" argument.
mstore(add(fmp, 36), amount) // Append the "amount" argument. Masking not required as it's a full 32 byte type.
success :=
and(
// Set success to whether the call reverted, if not we check it either
// returned exactly 1 (can't just be non-zero data), or had no return data.
or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
// We use 68 because the length of our calldata totals up like so: 4 + 32 * 2.
// We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.
// Counterintuitively, this call must be positioned second to the or() call in the
// surrounding and() call or else returndatasize() will be zero during the computation.
call(gas(), currency, 0, fmp, 68, 0, 32)
)
// Now clean the memory we used
mstore(fmp, 0) // 4 byte `selector` and 28 bytes of `to` were stored here
mstore(add(fmp, 0x20), 0) // 4 bytes of `to` and 28 bytes of `amount` were stored here
mstore(add(fmp, 0x40), 0) // 4 bytes of `amount` were stored here
}
// revert with ERC20TransferFailed, containing the bubbled up error as an argument
if (!success) {
CustomRevert.bubbleUpAndRevertWith(
Currency.unwrap(currency), IERC20Minimal.transfer.selector, ERC20TransferFailed.selector
);
}
}
}
function balanceOfSelf(Currency currency) internal view returns (uint256) {
if (currency.isAddressZero()) {
return address(this).balance;
} else {
return IERC20Minimal(Currency.unwrap(currency)).balanceOf(address(this));
}
}
function balanceOf(Currency currency, address owner) internal view returns (uint256) {
if (currency.isAddressZero()) {
return owner.balance;
} else {
return IERC20Minimal(Currency.unwrap(currency)).balanceOf(owner);
}
}
function isAddressZero(Currency currency) internal pure returns (bool) {
return Currency.unwrap(currency) == Currency.unwrap(ADDRESS_ZERO);
}
function toId(Currency currency) internal pure returns (uint256) {
return uint160(Currency.unwrap(currency));
}
// If the upper 12 bytes are non-zero, they will be zero-ed out
// Therefore, fromId() and toId() are not inverses of each other
function fromId(uint256 id) internal pure returns (Currency) {
return Currency.wrap(address(uint160(id)));
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {PoolKey} from "../types/PoolKey.sol";
import {BalanceDelta} from "../types/BalanceDelta.sol";
import {ModifyLiquidityParams, SwapParams} from "../types/PoolOperation.sol";
import {BeforeSwapDelta} from "../types/BeforeSwapDelta.sol";
/// @notice V4 decides whether to invoke specific hooks by inspecting the least significant bits
/// of the address that the hooks contract is deployed to.
/// For example, a hooks contract deployed to address: 0x0000000000000000000000000000000000002400
/// has the lowest bits '10 0100 0000 0000' which would cause the 'before initialize' and 'after add liquidity' hooks to be used.
/// See the Hooks library for the full spec.
/// @dev Should only be callable by the v4 PoolManager.
interface IHooks {
/// @notice The hook called before the state of a pool is initialized
/// @param sender The initial msg.sender for the initialize call
/// @param key The key for the pool being initialized
/// @param sqrtPriceX96 The sqrt(price) of the pool as a Q64.96
/// @return bytes4 The function selector for the hook
function beforeInitialize(address sender, PoolKey calldata key, uint160 sqrtPriceX96) external returns (bytes4);
/// @notice The hook called after the state of a pool is initialized
/// @param sender The initial msg.sender for the initialize call
/// @param key The key for the pool being initialized
/// @param sqrtPriceX96 The sqrt(price) of the pool as a Q64.96
/// @param tick The current tick after the state of a pool is initialized
/// @return bytes4 The function selector for the hook
function afterInitialize(address sender, PoolKey calldata key, uint160 sqrtPriceX96, int24 tick)
external
returns (bytes4);
/// @notice The hook called before liquidity is added
/// @param sender The initial msg.sender for the add liquidity call
/// @param key The key for the pool
/// @param params The parameters for adding liquidity
/// @param hookData Arbitrary data handed into the PoolManager by the liquidity provider to be passed on to the hook
/// @return bytes4 The function selector for the hook
function beforeAddLiquidity(
address sender,
PoolKey calldata key,
ModifyLiquidityParams calldata params,
bytes calldata hookData
) external returns (bytes4);
/// @notice The hook called after liquidity is added
/// @param sender The initial msg.sender for the add liquidity call
/// @param key The key for the pool
/// @param params The parameters for adding liquidity
/// @param delta The caller's balance delta after adding liquidity; the sum of principal delta, fees accrued, and hook delta
/// @param feesAccrued The fees accrued since the last time fees were collected from this position
/// @param hookData Arbitrary data handed into the PoolManager by the liquidity provider to be passed on to the hook
/// @return bytes4 The function selector for the hook
/// @return BalanceDelta The hook's delta in token0 and token1. Positive: the hook is owed/took currency, negative: the hook owes/sent currency
function afterAddLiquidity(
address sender,
PoolKey calldata key,
ModifyLiquidityParams calldata params,
BalanceDelta delta,
BalanceDelta feesAccrued,
bytes calldata hookData
) external returns (bytes4, BalanceDelta);
/// @notice The hook called before liquidity is removed
/// @param sender The initial msg.sender for the remove liquidity call
/// @param key The key for the pool
/// @param params The parameters for removing liquidity
/// @param hookData Arbitrary data handed into the PoolManager by the liquidity provider to be be passed on to the hook
/// @return bytes4 The function selector for the hook
function beforeRemoveLiquidity(
address sender,
PoolKey calldata key,
ModifyLiquidityParams calldata params,
bytes calldata hookData
) external returns (bytes4);
/// @notice The hook called after liquidity is removed
/// @param sender The initial msg.sender for the remove liquidity call
/// @param key The key for the pool
/// @param params The parameters for removing liquidity
/// @param delta The caller's balance delta after removing liquidity; the sum of principal delta, fees accrued, and hook delta
/// @param feesAccrued The fees accrued since the last time fees were collected from this position
/// @param hookData Arbitrary data handed into the PoolManager by the liquidity provider to be be passed on to the hook
/// @return bytes4 The function selector for the hook
/// @return BalanceDelta The hook's delta in token0 and token1. Positive: the hook is owed/took currency, negative: the hook owes/sent currency
function afterRemoveLiquidity(
address sender,
PoolKey calldata key,
ModifyLiquidityParams calldata params,
BalanceDelta delta,
BalanceDelta feesAccrued,
bytes calldata hookData
) external returns (bytes4, BalanceDelta);
/// @notice The hook called before a swap
/// @param sender The initial msg.sender for the swap call
/// @param key The key for the pool
/// @param params The parameters for the swap
/// @param hookData Arbitrary data handed into the PoolManager by the swapper to be be passed on to the hook
/// @return bytes4 The function selector for the hook
/// @return BeforeSwapDelta The hook's delta in specified and unspecified currencies. Positive: the hook is owed/took currency, negative: the hook owes/sent currency
/// @return uint24 Optionally override the lp fee, only used if three conditions are met: 1. the Pool has a dynamic fee, 2. the value's 2nd highest bit is set (23rd bit, 0x400000), and 3. the value is less than or equal to the maximum fee (1 million)
function beforeSwap(address sender, PoolKey calldata key, SwapParams calldata params, bytes calldata hookData)
external
returns (bytes4, BeforeSwapDelta, uint24);
/// @notice The hook called after a swap
/// @param sender The initial msg.sender for the swap call
/// @param key The key for the pool
/// @param params The parameters for the swap
/// @param delta The amount owed to the caller (positive) or owed to the pool (negative)
/// @param hookData Arbitrary data handed into the PoolManager by the swapper to be be passed on to the hook
/// @return bytes4 The function selector for the hook
/// @return int128 The hook's delta in unspecified currency. Positive: the hook is owed/took currency, negative: the hook owes/sent currency
function afterSwap(
address sender,
PoolKey calldata key,
SwapParams calldata params,
BalanceDelta delta,
bytes calldata hookData
) external returns (bytes4, int128);
/// @notice The hook called before donate
/// @param sender The initial msg.sender for the donate call
/// @param key The key for the pool
/// @param amount0 The amount of token0 being donated
/// @param amount1 The amount of token1 being donated
/// @param hookData Arbitrary data handed into the PoolManager by the donor to be be passed on to the hook
/// @return bytes4 The function selector for the hook
function beforeDonate(
address sender,
PoolKey calldata key,
uint256 amount0,
uint256 amount1,
bytes calldata hookData
) external returns (bytes4);
/// @notice The hook called after donate
/// @param sender The initial msg.sender for the donate call
/// @param key The key for the pool
/// @param amount0 The amount of token0 being donated
/// @param amount1 The amount of token1 being donated
/// @param hookData Arbitrary data handed into the PoolManager by the donor to be be passed on to the hook
/// @return bytes4 The function selector for the hook
function afterDonate(
address sender,
PoolKey calldata key,
uint256 amount0,
uint256 amount1,
bytes calldata hookData
) external returns (bytes4);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/// @title Minimal ERC20 interface for Uniswap
/// @notice Contains a subset of the full ERC20 interface that is used in Uniswap V3
interface IERC20Minimal {
/// @notice Returns an account's balance in the token
/// @param account The account for which to look up the number of tokens it has, i.e. its balance
/// @return The number of tokens held by the account
function balanceOf(address account) external view returns (uint256);
/// @notice Transfers the amount of token from the `msg.sender` to the recipient
/// @param recipient The account that will receive the amount transferred
/// @param amount The number of tokens to send from the sender to the recipient
/// @return Returns true for a successful transfer, false for an unsuccessful transfer
function transfer(address recipient, uint256 amount) external returns (bool);
/// @notice Returns the current allowance given to a spender by an owner
/// @param owner The account of the token owner
/// @param spender The account of the token spender
/// @return The current allowance granted by `owner` to `spender`
function allowance(address owner, address spender) external view returns (uint256);
/// @notice Sets the allowance of a spender from the `msg.sender` to the value `amount`
/// @param spender The account which will be allowed to spend a given amount of the owners tokens
/// @param amount The amount of tokens allowed to be used by `spender`
/// @return Returns true for a successful approval, false for unsuccessful
function approve(address spender, uint256 amount) external returns (bool);
/// @notice Transfers `amount` tokens from `sender` to `recipient` up to the allowance given to the `msg.sender`
/// @param sender The account from which the transfer will be initiated
/// @param recipient The recipient of the transfer
/// @param amount The amount of the transfer
/// @return Returns true for a successful transfer, false for unsuccessful
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
/// @notice Event emitted when tokens are transferred from one address to another, either via `#transfer` or `#transferFrom`.
/// @param from The account from which the tokens were sent, i.e. the balance decreased
/// @param to The account to which the tokens were sent, i.e. the balance increased
/// @param value The amount of tokens that were transferred
event Transfer(address indexed from, address indexed to, uint256 value);
/// @notice Event emitted when the approval amount for the spender of a given owner's tokens changes.
/// @param owner The account that approved spending of its tokens
/// @param spender The account for which the spending allowance was modified
/// @param value The new allowance from the owner to the spender
event Approval(address indexed owner, address indexed spender, uint256 value);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/// @title Library for reverting with custom errors efficiently
/// @notice Contains functions for reverting with custom errors with different argument types efficiently
/// @dev To use this library, declare `using CustomRevert for bytes4;` and replace `revert CustomError()` with
/// `CustomError.selector.revertWith()`
/// @dev The functions may tamper with the free memory pointer but it is fine since the call context is exited immediately
library CustomRevert {
/// @dev ERC-7751 error for wrapping bubbled up reverts
error WrappedError(address target, bytes4 selector, bytes reason, bytes details);
/// @dev Reverts with the selector of a custom error in the scratch space
function revertWith(bytes4 selector) internal pure {
assembly ("memory-safe") {
mstore(0, selector)
revert(0, 0x04)
}
}
/// @dev Reverts with a custom error with an address argument in the scratch space
function revertWith(bytes4 selector, address addr) internal pure {
assembly ("memory-safe") {
mstore(0, selector)
mstore(0x04, and(addr, 0xffffffffffffffffffffffffffffffffffffffff))
revert(0, 0x24)
}
}
/// @dev Reverts with a custom error with an int24 argument in the scratch space
function revertWith(bytes4 selector, int24 value) internal pure {
assembly ("memory-safe") {
mstore(0, selector)
mstore(0x04, signextend(2, value))
revert(0, 0x24)
}
}
/// @dev Reverts with a custom error with a uint160 argument in the scratch space
function revertWith(bytes4 selector, uint160 value) internal pure {
assembly ("memory-safe") {
mstore(0, selector)
mstore(0x04, and(value, 0xffffffffffffffffffffffffffffffffffffffff))
revert(0, 0x24)
}
}
/// @dev Reverts with a custom error with two int24 arguments
function revertWith(bytes4 selector, int24 value1, int24 value2) internal pure {
assembly ("memory-safe") {
let fmp := mload(0x40)
mstore(fmp, selector)
mstore(add(fmp, 0x04), signextend(2, value1))
mstore(add(fmp, 0x24), signextend(2, value2))
revert(fmp, 0x44)
}
}
/// @dev Reverts with a custom error with two uint160 arguments
function revertWith(bytes4 selector, uint160 value1, uint160 value2) internal pure {
assembly ("memory-safe") {
let fmp := mload(0x40)
mstore(fmp, selector)
mstore(add(fmp, 0x04), and(value1, 0xffffffffffffffffffffffffffffffffffffffff))
mstore(add(fmp, 0x24), and(value2, 0xffffffffffffffffffffffffffffffffffffffff))
revert(fmp, 0x44)
}
}
/// @dev Reverts with a custom error with two address arguments
function revertWith(bytes4 selector, address value1, address value2) internal pure {
assembly ("memory-safe") {
let fmp := mload(0x40)
mstore(fmp, selector)
mstore(add(fmp, 0x04), and(value1, 0xffffffffffffffffffffffffffffffffffffffff))
mstore(add(fmp, 0x24), and(value2, 0xffffffffffffffffffffffffffffffffffffffff))
revert(fmp, 0x44)
}
}
/// @notice bubble up the revert message returned by a call and revert with a wrapped ERC-7751 error
/// @dev this method can be vulnerable to revert data bombs
function bubbleUpAndRevertWith(
address revertingContract,
bytes4 revertingFunctionSelector,
bytes4 additionalContext
) internal pure {
bytes4 wrappedErrorSelector = WrappedError.selector;
assembly ("memory-safe") {
// Ensure the size of the revert data is a multiple of 32 bytes
let encodedDataSize := mul(div(add(returndatasize(), 31), 32), 32)
let fmp := mload(0x40)
// Encode wrapped error selector, address, function selector, offset, additional context, size, revert reason
mstore(fmp, wrappedErrorSelector)
mstore(add(fmp, 0x04), and(revertingContract, 0xffffffffffffffffffffffffffffffffffffffff))
mstore(
add(fmp, 0x24),
and(revertingFunctionSelector, 0xffffffff00000000000000000000000000000000000000000000000000000000)
)
// offset revert reason
mstore(add(fmp, 0x44), 0x80)
// offset additional context
mstore(add(fmp, 0x64), add(0xa0, encodedDataSize))
// size revert reason
mstore(add(fmp, 0x84), returndatasize())
// revert reason
returndatacopy(add(fmp, 0xa4), 0, returndatasize())
// size additional context
mstore(add(fmp, add(0xa4, encodedDataSize)), 0x04)
// additional context
mstore(
add(fmp, add(0xc4, encodedDataSize)),
and(additionalContext, 0xffffffff00000000000000000000000000000000000000000000000000000000)
)
revert(fmp, add(0xe4, encodedDataSize))
}
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {SafeCast} from "../libraries/SafeCast.sol";
/// @dev Two `int128` values packed into a single `int256` where the upper 128 bits represent the amount0
/// and the lower 128 bits represent the amount1.
type BalanceDelta is int256;
using {add as +, sub as -, eq as ==, neq as !=} for BalanceDelta global;
using BalanceDeltaLibrary for BalanceDelta global;
using SafeCast for int256;
function toBalanceDelta(int128 _amount0, int128 _amount1) pure returns (BalanceDelta balanceDelta) {
assembly ("memory-safe") {
balanceDelta := or(shl(128, _amount0), and(sub(shl(128, 1), 1), _amount1))
}
}
function add(BalanceDelta a, BalanceDelta b) pure returns (BalanceDelta) {
int256 res0;
int256 res1;
assembly ("memory-safe") {
let a0 := sar(128, a)
let a1 := signextend(15, a)
let b0 := sar(128, b)
let b1 := signextend(15, b)
res0 := add(a0, b0)
res1 := add(a1, b1)
}
return toBalanceDelta(res0.toInt128(), res1.toInt128());
}
function sub(BalanceDelta a, BalanceDelta b) pure returns (BalanceDelta) {
int256 res0;
int256 res1;
assembly ("memory-safe") {
let a0 := sar(128, a)
let a1 := signextend(15, a)
let b0 := sar(128, b)
let b1 := signextend(15, b)
res0 := sub(a0, b0)
res1 := sub(a1, b1)
}
return toBalanceDelta(res0.toInt128(), res1.toInt128());
}
function eq(BalanceDelta a, BalanceDelta b) pure returns (bool) {
return BalanceDelta.unwrap(a) == BalanceDelta.unwrap(b);
}
function neq(BalanceDelta a, BalanceDelta b) pure returns (bool) {
return BalanceDelta.unwrap(a) != BalanceDelta.unwrap(b);
}
/// @notice Library for getting the amount0 and amount1 deltas from the BalanceDelta type
library BalanceDeltaLibrary {
/// @notice A BalanceDelta of 0
BalanceDelta public constant ZERO_DELTA = BalanceDelta.wrap(0);
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)
}
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
import {PoolKey} from "../types/PoolKey.sol";
import {BalanceDelta} from "../types/BalanceDelta.sol";
/// @notice Parameter struct for `ModifyLiquidity` pool operations
struct ModifyLiquidityParams {
// the lower and upper tick of the position
int24 tickLower;
int24 tickUpper;
// how to modify the liquidity
int256 liquidityDelta;
// a value to set if you want unique liquidity positions at the same range
bytes32 salt;
}
/// @notice Parameter struct for `Swap` pool operations
struct SwapParams {
/// Whether to swap token0 for token1 or vice versa
bool zeroForOne;
/// The desired input amount if negative (exactIn), or the desired output amount if positive (exactOut)
int256 amountSpecified;
/// The sqrt price at which, if reached, the swap will stop executing
uint160 sqrtPriceLimitX96;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
// Return type of the beforeSwap hook.
// Upper 128 bits is the delta in specified tokens. Lower 128 bits is delta in unspecified tokens (to match the afterSwap hook)
type BeforeSwapDelta is int256;
// Creates a BeforeSwapDelta from specified and unspecified
function toBeforeSwapDelta(int128 deltaSpecified, int128 deltaUnspecified)
pure
returns (BeforeSwapDelta beforeSwapDelta)
{
assembly ("memory-safe") {
beforeSwapDelta := or(shl(128, deltaSpecified), and(sub(shl(128, 1), 1), deltaUnspecified))
}
}
/// @notice Library for getting the specified and unspecified deltas from the BeforeSwapDelta type
library BeforeSwapDeltaLibrary {
/// @notice A BeforeSwapDelta of 0
BeforeSwapDelta public constant ZERO_DELTA = BeforeSwapDelta.wrap(0);
/// extracts int128 from the upper 128 bits of the BeforeSwapDelta
/// returned by beforeSwap
function getSpecifiedDelta(BeforeSwapDelta delta) internal pure returns (int128 deltaSpecified) {
assembly ("memory-safe") {
deltaSpecified := sar(128, delta)
}
}
/// extracts int128 from the lower 128 bits of the BeforeSwapDelta
/// returned by beforeSwap and afterSwap
function getUnspecifiedDelta(BeforeSwapDelta delta) internal pure returns (int128 deltaUnspecified) {
assembly ("memory-safe") {
deltaUnspecified := signextend(15, delta)
}
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {CustomRevert} from "./CustomRevert.sol";
/// @title Safe casting methods
/// @notice Contains methods for safely casting between types
library SafeCast {
using CustomRevert for bytes4;
error SafeCastOverflow();
/// @notice Cast a uint256 to a uint160, revert on overflow
/// @param x The uint256 to be downcasted
/// @return y The downcasted integer, now type uint160
function toUint160(uint256 x) internal pure returns (uint160 y) {
y = uint160(x);
if (y != x) SafeCastOverflow.selector.revertWith();
}
/// @notice Cast a uint256 to a uint128, revert on overflow
/// @param x The uint256 to be downcasted
/// @return y The downcasted integer, now type uint128
function toUint128(uint256 x) internal pure returns (uint128 y) {
y = uint128(x);
if (x != y) SafeCastOverflow.selector.revertWith();
}
/// @notice Cast a int128 to a uint128, revert on overflow or underflow
/// @param x The int128 to be casted
/// @return y The casted integer, now type uint128
function toUint128(int128 x) internal pure returns (uint128 y) {
if (x < 0) SafeCastOverflow.selector.revertWith();
y = uint128(x);
}
/// @notice Cast a int256 to a int128, revert on overflow or underflow
/// @param x The int256 to be downcasted
/// @return y The downcasted integer, now type int128
function toInt128(int256 x) internal pure returns (int128 y) {
y = int128(x);
if (y != x) SafeCastOverflow.selector.revertWith();
}
/// @notice Cast a uint256 to a int256, revert on overflow
/// @param x The uint256 to be casted
/// @return y The casted integer, now type int256
function toInt256(uint256 x) internal pure returns (int256 y) {
y = int256(x);
if (y < 0) SafeCastOverflow.selector.revertWith();
}
/// @notice Cast a uint256 to a int128, revert on overflow
/// @param x The uint256 to be downcasted
/// @return The downcasted integer, now type int128
function toInt128(uint256 x) internal pure returns (int128) {
if (x >= 1 << 127) SafeCastOverflow.selector.revertWith();
return int128(int256(x));
}
}{
"remappings": [
"solmate/=node_modules/solmate/",
"@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/",
"openzeppelin/=node_modules/@openzeppelin/contracts/",
"openzeppelin-contracts/=node_modules/@openzeppelin/",
"forge-std/=node_modules/forge-std/src/",
"ds-test/=node_modules/ds-test/src/",
"v4-core/=node_modules/@uniswap/v4-core/",
"@uniswap/v4-core/=node_modules/@uniswap/v4-core/",
"v4-periphery/=node_modules/@uniswap/v4-periphery/",
"@uniswap/v4-periphery/=node_modules/@uniswap/v4-periphery/",
"uniswap-hooks/=node_modules/uniswap-hooks/src/",
"utils/=test/utils/",
"mocks/=test/mocks/",
"permit2/=node_modules/permit2/"
],
"optimizer": {
"enabled": true,
"runs": 10000
},
"metadata": {
"useLiteralContent": false,
"bytecodeHash": "ipfs",
"appendCBOR": true
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"evmVersion": "cancun",
"viaIR": true,
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_governance","type":"address"},{"internalType":"uint256","name":"_dailyBudget","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint24","name":"value","type":"uint24"},{"internalType":"uint24","name":"min","type":"uint24"},{"internalType":"uint24","name":"max","type":"uint24"}],"name":"InvalidFeeRange","type":"error"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"min","type":"uint256"},{"internalType":"uint256","name":"max","type":"uint256"}],"name":"ParameterOutOfRange","type":"error"},{"inputs":[],"name":"ZeroAddress","type":"error"},{"inputs":[],"name":"ZeroValue","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"PoolId","name":"poolId","type":"bytes32"},{"indexed":false,"internalType":"uint32","name":"factor","type":"uint32"}],"name":"BaseFeeFactorSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"PoolId","name":"poolId","type":"bytes32"},{"indexed":false,"internalType":"uint32","name":"stepPpm","type":"uint32"},{"indexed":false,"internalType":"uint32","name":"updateIntervalSecs","type":"uint32"}],"name":"BaseFeeParamsSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"PoolId","name":"poolId","type":"bytes32"},{"indexed":false,"internalType":"uint32","name":"decayWindow","type":"uint32"}],"name":"CapBudgetDecayWindowSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"newBudget","type":"uint32"}],"name":"DailyBudgetSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"decayWindow","type":"uint32"}],"name":"GlobalDecayWindowSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"PoolId","name":"poolId","type":"bytes32"},{"indexed":false,"internalType":"uint24","name":"manualFee","type":"uint24"}],"name":"ManualFeeSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"PoolId","name":"poolId","type":"bytes32"},{"indexed":false,"internalType":"uint24","name":"maxBaseFeePpm","type":"uint24"}],"name":"MaxBaseFeeSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"PoolId","name":"poolId","type":"bytes32"},{"indexed":false,"internalType":"uint24","name":"minBaseFeePpm","type":"uint24"}],"name":"MinBaseFeeSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"PoolId","name":"poolId","type":"bytes32"},{"indexed":false,"internalType":"uint32","name":"newBudget","type":"uint32"}],"name":"PoolDailyBudgetSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"PoolId","name":"poolId","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"polSharePpm","type":"uint256"}],"name":"PoolPOLShareChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"PoolId","name":"poolId","type":"bytes32"},{"indexed":false,"internalType":"uint32","name":"decayPeriod","type":"uint32"}],"name":"SurgeDecayPeriodSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"PoolId","name":"poolId","type":"bytes32"},{"indexed":false,"internalType":"uint24","name":"multiplier","type":"uint24"}],"name":"SurgeFeeMultiplierSet","type":"event"},{"inputs":[{"internalType":"PoolId","name":"poolId","type":"bytes32"}],"name":"clearManualFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"PoolId","name":"poolId","type":"bytes32"}],"name":"getBaseFeeFactor","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"PoolId","name":"poolId","type":"bytes32"}],"name":"getBaseFeeStepPpm","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"PoolId","name":"poolId","type":"bytes32"}],"name":"getBaseFeeUpdateIntervalSeconds","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"PoolId","name":"poolId","type":"bytes32"}],"name":"getCapBudgetDecayWindow","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"PoolId","name":"poolId","type":"bytes32"}],"name":"getDailyBudgetPpm","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getDefaultDailyBudgetPpm","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"PoolId","name":"","type":"bytes32"}],"name":"getDefaultMaxTicksPerBlock","outputs":[{"internalType":"uint24","name":"","type":"uint24"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"PoolId","name":"poolId","type":"bytes32"}],"name":"getManualFee","outputs":[{"internalType":"uint24","name":"manualFee","type":"uint24"},{"internalType":"bool","name":"isSet","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"PoolId","name":"poolId","type":"bytes32"}],"name":"getMaxBaseFee","outputs":[{"internalType":"uint24","name":"","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"PoolId","name":"poolId","type":"bytes32"}],"name":"getMinBaseFee","outputs":[{"internalType":"uint24","name":"","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"PoolId","name":"poolId","type":"bytes32"}],"name":"getPoolPOLShare","outputs":[{"internalType":"uint256","name":"poolSpecificPolShare","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"PoolId","name":"poolId","type":"bytes32"}],"name":"getSurgeDecayPeriodSeconds","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"PoolId","name":"poolId","type":"bytes32"}],"name":"getSurgeFeeMultiplierPpm","outputs":[{"internalType":"uint24","name":"","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"PoolId","name":"poolId","type":"bytes32"},{"internalType":"uint32","name":"factor","type":"uint32"}],"name":"setBaseFeeFactor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"PoolId","name":"poolId","type":"bytes32"},{"internalType":"uint32","name":"stepPpm","type":"uint32"},{"internalType":"uint32","name":"updateIntervalSecs","type":"uint32"}],"name":"setBaseFeeParams","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"PoolId","name":"poolId","type":"bytes32"},{"internalType":"uint32","name":"newCapBudgetDecayWindow","type":"uint32"}],"name":"setCapBudgetDecayWindow","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"newCapBudgetDailyPpm","type":"uint32"}],"name":"setDailyBudgetPpm","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"newCapBudgetDecayWindow","type":"uint32"}],"name":"setDecayWindow","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"PoolId","name":"poolId","type":"bytes32"},{"internalType":"uint24","name":"manualFee","type":"uint24"}],"name":"setManualFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"PoolId","name":"poolId","type":"bytes32"},{"internalType":"uint24","name":"newMaxFee","type":"uint24"}],"name":"setMaxBaseFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"PoolId","name":"poolId","type":"bytes32"},{"internalType":"uint24","name":"newMinFee","type":"uint24"}],"name":"setMinBaseFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"PoolId","name":"poolId","type":"bytes32"},{"internalType":"uint32","name":"newBudget","type":"uint32"}],"name":"setPoolDailyBudgetPpm","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"PoolId","name":"poolId","type":"bytes32"},{"internalType":"uint256","name":"newPolSharePpm","type":"uint256"}],"name":"setPoolPOLShare","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"PoolId","name":"poolId","type":"bytes32"},{"internalType":"uint32","name":"newSurgeDecayPeriodSeconds","type":"uint32"}],"name":"setSurgeDecayPeriodSeconds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"PoolId","name":"poolId","type":"bytes32"},{"internalType":"uint24","name":"multiplier","type":"uint24"}],"name":"setSurgeFeeMultiplierPpm","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
6080346100f057601f6114f638819003918201601f19168301916001600160401b038311848410176100f45780849260409485528339810103126100f05780516001600160a01b03811691908290036100f057602001515f80546001600160a01b03191683178155604051929081907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08180a3156100e157806100d4575063ffffffff620f42405b1663ffffffff19600654161760065562ed4e0063ffffffff1960085416176008556113ed90816101098239f35b63ffffffff8091166100a7565b63d92e233d60e01b5f5260045ffd5b5f80fd5b634e487b7160e01b5f52604160045260245ffdfe60806040526004361015610011575f80fd5b5f3560e01c806319387f22146110885780631b80db7514610fc05780632020a71214610f80578063265f001214610ed557806331e2171514610e8d57806340943f8314610e6f5780634c2d4eee14610e335780634ca3d1e814610e155780635233477f14610df2578063594fce1e14610c8f5780635eddee2114610c7357806365007e5714610af5578063764ec8b9146109f45780638609b0d81461095e5780638da5cb5b1461092c5780638f349b1b1461090257806391dce1a1146108bf578063a574ccb3146107de578063b1dce181146107c0578063bea1c84414610794578063c567d3bc146106b9578063c606f7e814610675578063c6be21a114610559578063d586643514610476578063dddada05146102fa578063f1f859671461021e578063f2fde38b1461017c5763f32a75ca1461014d575f80fd5b3461017857602060031936011261017857602061016b600435611380565b62ffffff60405191168152f35b5f80fd5b346101785760206003193601126101785760043573ffffffffffffffffffffffffffffffffffffffff811680910361017857807fffffffffffffffffffffffff00000000000000000000000000000000000000005f546101f373ffffffffffffffffffffffffffffffffffffffff821633146111df565b16175f55337f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e05f80a3005b346101785760206003193601126101785760043561025473ffffffffffffffffffffffffffffffffffffffff5f541633146111df565b805f52600260205260ff60405f20541661026a57005b805f52600160205260405f207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000008154169055805f52600260205260405f207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0081541690557f9083d025f8c64d59acea1fdf714c5516cf7a6a0ec3d8ad02dba4b4020581670e60206040515f8152a2005b3461017857610308366111bd565b61032a73ffffffffffffffffffffffffffffffffffffffff5f541633146111df565b6040517f4ca3d1e8000000000000000000000000000000000000000000000000000000008152826004820152602081602481305afa801561046b5762ffffff915f9161043c575b50169062ffffff8116918083108015610431575b6103fc57507f2f5debd6daca65c6366789854a2dc3af21dc997a9a5efea24aaa5909bf2b92a991602091845f526004835260405f20907fffffffffffffffffffffffffffffffffffffffffffff000000ffffffffffffff69ffffff0000000000000083549260381b169116179055604051908152a2005b827f2541552c000000000000000000000000000000000000000000000000000000005f5260045260245261c35060445260645ffd5b5061c3508311610385565b61045e915060203d602011610464575b61045681836112b3565b8101906112f4565b84610371565b503d61044c565b6040513d5f823e3d90fd5b346101785760406003193601126101785760043563ffffffff610497611197565b6104b973ffffffffffffffffffffffffffffffffffffffff5f541633146111df565b1680151580610543575b61050c5760207fd7e72b0fc5beacd7d45da90e00eae118e8631408a96ec944fca72198d70a0aba91835f526007825260405f208163ffffffff19825416179055604051908152a2005b7fd3f93ee8000000000000000000000000000000000000000000000000000000005f5260045260016024526298968060445260645ffd5b5060018110806104c357506298968081116104c3565b346101785762ffffff61056b366111bd565b61059073ffffffffffffffffffffffffffffffffffffffff5f949394541633146111df565b1660648110801561066a575b6106345760207f9083d025f8c64d59acea1fdf714c5516cf7a6a0ec3d8ad02dba4b4020581670e91835f526001825260405f20817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000825416179055835f526002825260405f2060017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00825416179055604051908152a2005b7fd3f93ee8000000000000000000000000000000000000000000000000000000005f52600452606460245261c35060445260645ffd5b5061c350811161059c565b34610178576020600319360112610178576040600435805f52600160205262ffffff825f205416905f52600260205260ff825f205416825191825215156020820152f35b346101785760406003193601126101785760043563ffffffff6106da611197565b6106fc73ffffffffffffffffffffffffffffffffffffffff5f541633146111df565b1680158015610787575b61074f5760207f66ee5e9b760bb90b7fd9e7d2d5a734bbad7ad1a680014d26d7e645d8e9e166ad91835f526004825260405f208163ffffffff19825416179055604051908152a2005b7fd3f93ee8000000000000000000000000000000000000000000000000000000005f52600452600160245263ffffffff60445260645ffd5b5063ffffffff8111610706565b346101785760206003193601126101785760206107b2600435611347565b63ffffffff60405191168152f35b3461017857602060031936011261017857602061016b60043561130f565b346101785760406003193601126101785760043563ffffffff6107ff611197565b61082173ffffffffffffffffffffffffffffffffffffffff5f541633146111df565b16801515806108aa575b6108745760207fc8d20789bc2cb7bff2e11840599da787d4a2b2df695b7e772f2679356159cddc91835f526009825260405f208163ffffffff19825416179055604051908152a2005b7fd3f93ee8000000000000000000000000000000000000000000000000000000005f5260045260016024526103e860445260645ffd5b50600181108061082b57506103e8811161082b565b34610178576020600319360112610178576004355f52600960205263ffffffff60405f20541680155f146108fa575060405160648152602090f35b6020906107b2565b34610178576020600319360112610178576004355f526003602052602060405f2054604051908152f35b34610178575f60031936011261017857602073ffffffffffffffffffffffffffffffffffffffff5f5416604051908152f35b346101785760206003193601126101785763ffffffff61097c6111aa565b61099e73ffffffffffffffffffffffffffffffffffffffff5f541633146111df565b16801580156109e8575b61050c576020817f3f1bd9e18fc1d3973140743a18a170a8d611e75425f827c4a96f2454326f68859263ffffffff196006541617600655604051908152a1005b506298968081116109a8565b3461017857610a02366111bd565b610a2473ffffffffffffffffffffffffffffffffffffffff5f541633146111df565b62ffffff81169081158015610ae9575b610ab1577ff6dfc5609f3aae34feebcd990ea035721d1dcdf52d7ce41d2075ceddec87595391602091845f526004835260405f20907fffffffffffffffffffffffffffffff000000ffffffffffffffffffffffffffff70ffffff000000000000000000000000000083549260701b169116179055604051908152a2005b507fd3f93ee8000000000000000000000000000000000000000000000000000000005f526004526001602452622dc6c060445260645ffd5b50622dc6c08211610a34565b3461017857606060031936011261017857600435610b11611197565b6044359063ffffffff82168092036101785763ffffffff90610b4b73ffffffffffffffffffffffffffffffffffffffff5f541633146111df565b1690620186a08211610c3c57801561074f5760405191604083019183831067ffffffffffffffff841117610c0f577f0e49e7eb0b09c860e745288083a908c9113d3782c23a133a490c171adca7277393604093845282815260208101828152865f52600560205263ffffffff80865f209351161663ffffffff19835416178255517fffffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffff67ffffffff0000000083549260201b16911617905582519182526020820152a2005b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b507fd3f93ee8000000000000000000000000000000000000000000000000000000005f526004525f602452620186a060445260645ffd5b3461017857602060031936011261017857602060405160328152f35b3461017857610c9d366111bd565b610cbf73ffffffffffffffffffffffffffffffffffffffff5f541633146111df565b604051907ff32a75ca000000000000000000000000000000000000000000000000000000008252826004830152602082602481305afa91821561046b575f92610dd1575b5062ffffff811691606483108015610dc3575b610d8957507f8933b881da6cef5bce0dd8e24a6e051cc8621a1502bbde1d4bd6e76f791b0d3491602091845f526004835260405f20907fffffffffffffffffffffffffffffffffffffffffffffffffff000000ffffffff66ffffff00000000835492861b169116179055604051908152a2005b62ffffff90837f2541552c000000000000000000000000000000000000000000000000000000005f5260045260646024521660445260645ffd5b5062ffffff81168311610d16565b610deb91925060203d6020116104645761045681836112b3565b9083610d03565b34610178575f60031936011261017857602063ffffffff60065416604051908152f35b3461017857602060031936011261017857602061016b60043561127d565b34610178576020600319360112610178576004355f52600560205263ffffffff60405f20541680155f146108fa5750604051614e208152602090f35b346101785760206003193601126101785760206107b2600435611244565b34610178576020600319360112610178576004355f52600760205263ffffffff60405f20541680155f146108fa5750602063ffffffff6006541663ffffffff60405191168152f35b346101785760206003193601126101785763ffffffff610ef36111aa565b610f1573ffffffffffffffffffffffffffffffffffffffff5f541633146111df565b168015610f58576020817f0caae632587dc39fce6f52625e76b77fc72c9973598cce01fdc747f944365c8f9263ffffffff196008541617600855604051908152a1005b7f7c946ed7000000000000000000000000000000000000000000000000000000005f5260045ffd5b34610178576020600319360112610178576004355f52600560205263ffffffff60405f205460201c1680155f146108fa5750604051620151808152602090f35b3461017857604060031936011261017857600435602435610ff973ffffffffffffffffffffffffffffffffffffffff5f541633146111df565b620f4240811161105257815f5260036020528060405f20540361101857005b60207fc22c4cd36600aa7bb9e64762f7b5cd1fb2f5f8d101b8f4c24e6c41e53beab3db91835f52600382528060405f2055604051908152a2005b7fd3f93ee8000000000000000000000000000000000000000000000000000000005f526004525f602452620f424060445260645ffd5b34610178576040600319360112610178576004356110a4611197565b6110c673ffffffffffffffffffffffffffffffffffffffff5f541633146111df565b63ffffffff811690603c8210801561118b575b611153577fd2bd771962d916ee2dbf5ed4eeb2544de7646b2afb24ce617921f5f5b24de4b191602091845f526004835260405f20907fffffffffffffffffffffffffffffffffffff00000000ffffffffffffffffffff6dffffffff0000000000000000000083549260501b169116179055604051908152a2005b507fd3f93ee8000000000000000000000000000000000000000000000000000000005f52600452603c6024526201518060445260645ffd5b506201518082116110d9565b6024359063ffffffff8216820361017857565b6004359063ffffffff8216820361017857565b6003196040910112610178576004359060243562ffffff811681036101785790565b156111e657565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a454400000000000000000000000000000000000000006044820152fd5b805f52600460205263ffffffff60405f205416611268575063ffffffff6008541690565b5f52600460205263ffffffff60405f20541690565b805f52600460205262ffffff60405f205460201c1661129c5750606490565b5f52600460205262ffffff60405f205460201c1690565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff821117610c0f57604052565b90816020910312610178575162ffffff811681036101785790565b805f52600460205262ffffff60405f205460701c166113305750622dc6c090565b5f52600460205262ffffff60405f205460701c1690565b805f52600460205263ffffffff60405f205460501c166113685750610e1090565b5f52600460205263ffffffff60405f205460501c1690565b805f52600460205262ffffff60405f205460381c166113a0575061c35090565b5f52600460205262ffffff60405f205460381c169056fea2646970667358221220a17cd97e008e54202ec70dbaa5c9805952c5d5cf7900205958978e11cb99473964736f6c634300081b003300000000000000000000000036b89a2be57541e9e1f0b44cb085e573192f15140000000000000000000000000000000000000000000000000000000000000000
Deployed Bytecode
0x60806040526004361015610011575f80fd5b5f3560e01c806319387f22146110885780631b80db7514610fc05780632020a71214610f80578063265f001214610ed557806331e2171514610e8d57806340943f8314610e6f5780634c2d4eee14610e335780634ca3d1e814610e155780635233477f14610df2578063594fce1e14610c8f5780635eddee2114610c7357806365007e5714610af5578063764ec8b9146109f45780638609b0d81461095e5780638da5cb5b1461092c5780638f349b1b1461090257806391dce1a1146108bf578063a574ccb3146107de578063b1dce181146107c0578063bea1c84414610794578063c567d3bc146106b9578063c606f7e814610675578063c6be21a114610559578063d586643514610476578063dddada05146102fa578063f1f859671461021e578063f2fde38b1461017c5763f32a75ca1461014d575f80fd5b3461017857602060031936011261017857602061016b600435611380565b62ffffff60405191168152f35b5f80fd5b346101785760206003193601126101785760043573ffffffffffffffffffffffffffffffffffffffff811680910361017857807fffffffffffffffffffffffff00000000000000000000000000000000000000005f546101f373ffffffffffffffffffffffffffffffffffffffff821633146111df565b16175f55337f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e05f80a3005b346101785760206003193601126101785760043561025473ffffffffffffffffffffffffffffffffffffffff5f541633146111df565b805f52600260205260ff60405f20541661026a57005b805f52600160205260405f207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000008154169055805f52600260205260405f207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0081541690557f9083d025f8c64d59acea1fdf714c5516cf7a6a0ec3d8ad02dba4b4020581670e60206040515f8152a2005b3461017857610308366111bd565b61032a73ffffffffffffffffffffffffffffffffffffffff5f541633146111df565b6040517f4ca3d1e8000000000000000000000000000000000000000000000000000000008152826004820152602081602481305afa801561046b5762ffffff915f9161043c575b50169062ffffff8116918083108015610431575b6103fc57507f2f5debd6daca65c6366789854a2dc3af21dc997a9a5efea24aaa5909bf2b92a991602091845f526004835260405f20907fffffffffffffffffffffffffffffffffffffffffffff000000ffffffffffffff69ffffff0000000000000083549260381b169116179055604051908152a2005b827f2541552c000000000000000000000000000000000000000000000000000000005f5260045260245261c35060445260645ffd5b5061c3508311610385565b61045e915060203d602011610464575b61045681836112b3565b8101906112f4565b84610371565b503d61044c565b6040513d5f823e3d90fd5b346101785760406003193601126101785760043563ffffffff610497611197565b6104b973ffffffffffffffffffffffffffffffffffffffff5f541633146111df565b1680151580610543575b61050c5760207fd7e72b0fc5beacd7d45da90e00eae118e8631408a96ec944fca72198d70a0aba91835f526007825260405f208163ffffffff19825416179055604051908152a2005b7fd3f93ee8000000000000000000000000000000000000000000000000000000005f5260045260016024526298968060445260645ffd5b5060018110806104c357506298968081116104c3565b346101785762ffffff61056b366111bd565b61059073ffffffffffffffffffffffffffffffffffffffff5f949394541633146111df565b1660648110801561066a575b6106345760207f9083d025f8c64d59acea1fdf714c5516cf7a6a0ec3d8ad02dba4b4020581670e91835f526001825260405f20817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000825416179055835f526002825260405f2060017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00825416179055604051908152a2005b7fd3f93ee8000000000000000000000000000000000000000000000000000000005f52600452606460245261c35060445260645ffd5b5061c350811161059c565b34610178576020600319360112610178576040600435805f52600160205262ffffff825f205416905f52600260205260ff825f205416825191825215156020820152f35b346101785760406003193601126101785760043563ffffffff6106da611197565b6106fc73ffffffffffffffffffffffffffffffffffffffff5f541633146111df565b1680158015610787575b61074f5760207f66ee5e9b760bb90b7fd9e7d2d5a734bbad7ad1a680014d26d7e645d8e9e166ad91835f526004825260405f208163ffffffff19825416179055604051908152a2005b7fd3f93ee8000000000000000000000000000000000000000000000000000000005f52600452600160245263ffffffff60445260645ffd5b5063ffffffff8111610706565b346101785760206003193601126101785760206107b2600435611347565b63ffffffff60405191168152f35b3461017857602060031936011261017857602061016b60043561130f565b346101785760406003193601126101785760043563ffffffff6107ff611197565b61082173ffffffffffffffffffffffffffffffffffffffff5f541633146111df565b16801515806108aa575b6108745760207fc8d20789bc2cb7bff2e11840599da787d4a2b2df695b7e772f2679356159cddc91835f526009825260405f208163ffffffff19825416179055604051908152a2005b7fd3f93ee8000000000000000000000000000000000000000000000000000000005f5260045260016024526103e860445260645ffd5b50600181108061082b57506103e8811161082b565b34610178576020600319360112610178576004355f52600960205263ffffffff60405f20541680155f146108fa575060405160648152602090f35b6020906107b2565b34610178576020600319360112610178576004355f526003602052602060405f2054604051908152f35b34610178575f60031936011261017857602073ffffffffffffffffffffffffffffffffffffffff5f5416604051908152f35b346101785760206003193601126101785763ffffffff61097c6111aa565b61099e73ffffffffffffffffffffffffffffffffffffffff5f541633146111df565b16801580156109e8575b61050c576020817f3f1bd9e18fc1d3973140743a18a170a8d611e75425f827c4a96f2454326f68859263ffffffff196006541617600655604051908152a1005b506298968081116109a8565b3461017857610a02366111bd565b610a2473ffffffffffffffffffffffffffffffffffffffff5f541633146111df565b62ffffff81169081158015610ae9575b610ab1577ff6dfc5609f3aae34feebcd990ea035721d1dcdf52d7ce41d2075ceddec87595391602091845f526004835260405f20907fffffffffffffffffffffffffffffff000000ffffffffffffffffffffffffffff70ffffff000000000000000000000000000083549260701b169116179055604051908152a2005b507fd3f93ee8000000000000000000000000000000000000000000000000000000005f526004526001602452622dc6c060445260645ffd5b50622dc6c08211610a34565b3461017857606060031936011261017857600435610b11611197565b6044359063ffffffff82168092036101785763ffffffff90610b4b73ffffffffffffffffffffffffffffffffffffffff5f541633146111df565b1690620186a08211610c3c57801561074f5760405191604083019183831067ffffffffffffffff841117610c0f577f0e49e7eb0b09c860e745288083a908c9113d3782c23a133a490c171adca7277393604093845282815260208101828152865f52600560205263ffffffff80865f209351161663ffffffff19835416178255517fffffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffff67ffffffff0000000083549260201b16911617905582519182526020820152a2005b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b507fd3f93ee8000000000000000000000000000000000000000000000000000000005f526004525f602452620186a060445260645ffd5b3461017857602060031936011261017857602060405160328152f35b3461017857610c9d366111bd565b610cbf73ffffffffffffffffffffffffffffffffffffffff5f541633146111df565b604051907ff32a75ca000000000000000000000000000000000000000000000000000000008252826004830152602082602481305afa91821561046b575f92610dd1575b5062ffffff811691606483108015610dc3575b610d8957507f8933b881da6cef5bce0dd8e24a6e051cc8621a1502bbde1d4bd6e76f791b0d3491602091845f526004835260405f20907fffffffffffffffffffffffffffffffffffffffffffffffffff000000ffffffff66ffffff00000000835492861b169116179055604051908152a2005b62ffffff90837f2541552c000000000000000000000000000000000000000000000000000000005f5260045260646024521660445260645ffd5b5062ffffff81168311610d16565b610deb91925060203d6020116104645761045681836112b3565b9083610d03565b34610178575f60031936011261017857602063ffffffff60065416604051908152f35b3461017857602060031936011261017857602061016b60043561127d565b34610178576020600319360112610178576004355f52600560205263ffffffff60405f20541680155f146108fa5750604051614e208152602090f35b346101785760206003193601126101785760206107b2600435611244565b34610178576020600319360112610178576004355f52600760205263ffffffff60405f20541680155f146108fa5750602063ffffffff6006541663ffffffff60405191168152f35b346101785760206003193601126101785763ffffffff610ef36111aa565b610f1573ffffffffffffffffffffffffffffffffffffffff5f541633146111df565b168015610f58576020817f0caae632587dc39fce6f52625e76b77fc72c9973598cce01fdc747f944365c8f9263ffffffff196008541617600855604051908152a1005b7f7c946ed7000000000000000000000000000000000000000000000000000000005f5260045ffd5b34610178576020600319360112610178576004355f52600560205263ffffffff60405f205460201c1680155f146108fa5750604051620151808152602090f35b3461017857604060031936011261017857600435602435610ff973ffffffffffffffffffffffffffffffffffffffff5f541633146111df565b620f4240811161105257815f5260036020528060405f20540361101857005b60207fc22c4cd36600aa7bb9e64762f7b5cd1fb2f5f8d101b8f4c24e6c41e53beab3db91835f52600382528060405f2055604051908152a2005b7fd3f93ee8000000000000000000000000000000000000000000000000000000005f526004525f602452620f424060445260645ffd5b34610178576040600319360112610178576004356110a4611197565b6110c673ffffffffffffffffffffffffffffffffffffffff5f541633146111df565b63ffffffff811690603c8210801561118b575b611153577fd2bd771962d916ee2dbf5ed4eeb2544de7646b2afb24ce617921f5f5b24de4b191602091845f526004835260405f20907fffffffffffffffffffffffffffffffffffff00000000ffffffffffffffffffff6dffffffff0000000000000000000083549260501b169116179055604051908152a2005b507fd3f93ee8000000000000000000000000000000000000000000000000000000005f52600452603c6024526201518060445260645ffd5b506201518082116110d9565b6024359063ffffffff8216820361017857565b6004359063ffffffff8216820361017857565b6003196040910112610178576004359060243562ffffff811681036101785790565b156111e657565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a454400000000000000000000000000000000000000006044820152fd5b805f52600460205263ffffffff60405f205416611268575063ffffffff6008541690565b5f52600460205263ffffffff60405f20541690565b805f52600460205262ffffff60405f205460201c1661129c5750606490565b5f52600460205262ffffff60405f205460201c1690565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff821117610c0f57604052565b90816020910312610178575162ffffff811681036101785790565b805f52600460205262ffffff60405f205460701c166113305750622dc6c090565b5f52600460205262ffffff60405f205460701c1690565b805f52600460205263ffffffff60405f205460501c166113685750610e1090565b5f52600460205263ffffffff60405f205460501c1690565b805f52600460205262ffffff60405f205460381c166113a0575061c35090565b5f52600460205262ffffff60405f205460381c169056fea2646970667358221220a17cd97e008e54202ec70dbaa5c9805952c5d5cf7900205958978e11cb99473964736f6c634300081b0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000036b89a2be57541e9e1f0b44cb085e573192f15140000000000000000000000000000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : _governance (address): 0x36b89a2Be57541e9e1f0B44cb085e573192F1514
Arg [1] : _dailyBudget (uint256): 0
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 00000000000000000000000036b89a2be57541e9e1f0b44cb085e573192f1514
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000000
Multichain Portfolio | 34 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
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.