Source Code
Overview
ETH Balance
0 ETH
Eth Value
$0.00Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
V3FactoryOwner
Compiler Version
v0.8.23+commit.f704f362
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.23;
import {IUniswapV3PoolOwnerActions} from "src/interfaces/IUniswapV3PoolOwnerActions.sol";
import {IUniswapV3FactoryOwnerActions} from "src/interfaces/IUniswapV3FactoryOwnerActions.sol";
import {INotifiableRewardReceiver} from "src/interfaces/INotifiableRewardReceiver.sol";
import {IERC20} from "openzeppelin/token/ERC20/IERC20.sol";
import {SafeERC20} from "openzeppelin/token/ERC20/utils/SafeERC20.sol";
/// @title V3FactoryOwner
/// @author ScopeLift
/// @notice A contract that can serve as the owner of the Uniswap v3 factory. This contract itself
/// has an admin. That admin retains the exclusive right to call privileged methods on the v3
/// factory, and on pools which it has deployed, via passthrough methods. This includes the ability
/// to enable fee amounts on the factory, and set protocol fees on individual pools. The admin can
/// also set a new admin.
///
/// One privileged function that is _not_ reserved exclusively for the admin is the ability to
/// collect protocol fees from a pool. This method is instead exposed publicly by this contract's
/// `claimFees` method. That method collects fees from the protocol as long as the caller pays for
/// them with a transfer of a designated amount of a designated token. That payout is forwarded
/// to a reward receiver.
///
/// In the context of the broader system, it is expected that this contract's REWARD_RECEIVER is
/// a deployment of the `UniStaker` contract. It is expected the admin of this contract will be the
/// Uniswap Governance timelock. It is expected governance will transfer
/// ownership of the factory to an instance of this contract, and turn on protocol fees for select
/// pools. It is also expected a competitive market of seekers will emerge racing to "buy" the fees
/// for an arbitrage opportunity.
contract V3FactoryOwner {
using SafeERC20 for IERC20;
/// @notice Emitted when a user pays the payout and claims the fees from a given v3 pool.
/// @param pool The v3 pool from which protocol fees were claimed.
/// @param caller The address which executes the call to claim the fees.
/// @param recipient The address to which the claimed pool fees are sent.
/// @param amount0 The raw amount of token0 fees claimed from the pool.
/// @param amount1 The raw amount token1 fees claimed from the pool.
event FeesClaimed(
address indexed pool,
address indexed caller,
address indexed recipient,
uint256 amount0,
uint256 amount1
);
/// @notice Emitted when the existing admin designates a new address as the admin.
event AdminSet(address indexed oldAmin, address indexed newAdmin);
/// @notice Emitted when the admin updates the payout amount.
event PayoutAmountSet(uint256 indexed oldPayoutAmount, uint256 indexed newPayoutAmount);
/// @notice Thrown when an unauthorized account calls a privileged function.
error V3FactoryOwner__Unauthorized();
/// @notice Thrown if the proposed admin is the zero address.
error V3FactoryOwner__InvalidAddress();
/// @notice Thrown if the proposed payout amount is zero.
error V3FactoryOwner__InvalidPayoutAmount();
/// @notice Thrown when the fees collected from a pool are less than the caller expects.
error V3FactoryOwner__InsufficientFeesCollected();
/// @notice The instance of the Uniswap v3 factory contract which this contract will own.
IUniswapV3FactoryOwnerActions public immutable FACTORY;
/// @notice The ERC-20 token which must be used to pay for fees when claiming pool fees.
IERC20 public immutable PAYOUT_TOKEN;
/// @notice The raw amount of the payout token which is paid by a user when claiming pool fees.
uint256 public payoutAmount;
/// @notice The contract that receives the payout and is notified via method call, when pool fees
/// are claimed.
INotifiableRewardReceiver public immutable REWARD_RECEIVER;
/// @notice The address that can call privileged methods, including passthrough owner functions
/// to the factory itself.
address public admin;
/// @param _admin The initial admin address for this deployment. Cannot be zero address.
/// @param _factory The v3 factory instance for which this deployment will serve as owner.
/// @param _payoutToken The ERC-20 token in which payouts will be denominated.
/// @param _payoutAmount The initial raw amount of the payout token required to claim fees from
/// a pool.
/// @param _rewardReceiver The contract that will receive the payout when fees are claimed.
constructor(
address _admin,
IUniswapV3FactoryOwnerActions _factory,
IERC20 _payoutToken,
uint256 _payoutAmount,
INotifiableRewardReceiver _rewardReceiver
) {
if (_admin == address(0)) revert V3FactoryOwner__InvalidAddress();
if (_payoutAmount == 0) revert V3FactoryOwner__InvalidPayoutAmount();
admin = _admin;
FACTORY = _factory;
PAYOUT_TOKEN = _payoutToken;
payoutAmount = _payoutAmount;
REWARD_RECEIVER = _rewardReceiver;
emit AdminSet(address(0), _admin);
emit PayoutAmountSet(0, _payoutAmount);
}
/// @notice Pass the admin role to a new address. Must be called by the existing admin.
/// @param _newAdmin The address that will be the admin after this call completes.
function setAdmin(address _newAdmin) external {
_revertIfNotAdmin();
if (_newAdmin == address(0)) revert V3FactoryOwner__InvalidAddress();
emit AdminSet(admin, _newAdmin);
admin = _newAdmin;
}
/// @notice Update the payout amount to a new value. Must be called by admin.
/// @param _newPayoutAmount The value that will be the new payout amount.
function setPayoutAmount(uint256 _newPayoutAmount) external {
_revertIfNotAdmin();
if (_newPayoutAmount == 0) revert V3FactoryOwner__InvalidPayoutAmount();
emit PayoutAmountSet(payoutAmount, _newPayoutAmount);
payoutAmount = _newPayoutAmount;
}
/// @notice Passthrough method that enables a fee amount on the factory. Must be called by the
/// admin.
/// @param _fee The fee param to forward to the factory.
/// @param _tickSpacing The tick spacing param to forward to the factory.
/// @dev See docs on IUniswapV3FactoryOwnerActions for more information on forwarded params.
function enableFeeAmount(uint24 _fee, int24 _tickSpacing) external {
_revertIfNotAdmin();
FACTORY.enableFeeAmount(_fee, _tickSpacing);
}
/// @notice Passthrough method that sets the protocol fee on a v3 pool. Must be called by the
/// admin.
/// @param _pool The Uniswap v3 pool on which the protocol fee is being set.
/// @param _feeProtocol0 The fee protocol 0 param to forward to the pool.
/// @param _feeProtocol1 The fee protocol 1 parm to forward to the pool.
/// @dev See docs on IUniswapV3PoolOwnerActions for more information on forwarded params.
function setFeeProtocol(
IUniswapV3PoolOwnerActions _pool,
uint8 _feeProtocol0,
uint8 _feeProtocol1
) external {
_revertIfNotAdmin();
_pool.setFeeProtocol(_feeProtocol0, _feeProtocol1);
}
/// @notice Public method that allows any caller to claim the protocol fees accrued by a given
/// Uniswap v3 pool contract. Caller must pre-approve this factory owner contract on the payout
/// token contract for at least the payout amount, which is transferred from the caller to the
/// reward receiver. The reward receiver is "notified" of the payout via a method call. The
/// protocol fees collected are sent to a receiver of the caller's specification.
///
/// A quick example can help illustrate why an external party, such as an MEV searcher, would be
/// incentivized to call this method. Imagine, purely for the sake of example, that protocol fees
/// have been activated for the USDC/USDT stablecoin v3 pool. Imagine also the payout token and
/// payout amount are WETH and 10e18 respectively. Finally, assume the spot USD price of ETH is
/// $2,500, and both stablecoins are trading at their $1 peg. As regular users trade against the
/// USDC/USDT pool, protocol fees amass in the pool contract in both stablecoins. Once the fees
/// in the pool total more than 25,000 in stablecoins, it becomes profitable for an external
/// party to arbitrage the fees by calling this method, paying 10 WETH (worth $25K) and getting
/// more than $25K worth of stablecoins. (This ignores other details, which real searchers would
/// take into consideration, such as the gas/builder fee they would pay to call the method).
///
/// The same mechanic applies regardless of what the pool currencies, payout token, or payout
/// amount are. Effectively, as each pool accrues fees, it eventually becomes possible to "buy"
/// the pool fees for less than they are valued by "paying" the the payout amount of the payout
/// token.
/// `payoutAmount` may be changed by the admin (governance). Any proposal that changes this amount
/// is expected to be subject to the governance process, including a timelocked execution, and so
/// it's unlikely that a caller would be surprised by a change in this value. Still, callers
/// should be aware of the edge case where:
/// 1. The caller grants a higher-than-necessary payout token approval to this factory.
/// 2. caller's claimFee transaction is in the mempool.
/// 3. the payoutAmount is changed.
/// 4. the claimFee transaction is now included in a block.
/// @param _pool The Uniswap v3 pool contract from which protocol fees are being collected.
/// @param _recipient The address to which collected protocol fees will be transferred.
/// @param _amount0Requested The amount0Requested param to forward to the pool's collectProtocol
/// method. Its maximum value will be `protocolFees.token0 - 1`.
/// @param _amount1Requested The amount1Requested param to forward to the pool's collectProtocol
/// method. Its maximum value will be `protocolFees.token1 - 1`.
/// @return _amount0 The amount0 fees collected, returned by the pool's collectProtocol method.
/// @return _amount1 The amount1 fees collected, returned by the pool's collectProtocol method.
/// @dev The `UniswapV3Pool contract allows claiming a maximum of the total accrued fees minus 1.
/// We highly recommend checking the source code of the `UniswapV3Pool` contract in order to
/// better understand the potential constraints of the forwarded params.
function claimFees(
IUniswapV3PoolOwnerActions _pool,
address _recipient,
uint128 _amount0Requested,
uint128 _amount1Requested
) external returns (uint128, uint128) {
PAYOUT_TOKEN.safeTransferFrom(msg.sender, address(REWARD_RECEIVER), payoutAmount);
REWARD_RECEIVER.notifyRewardAmount(payoutAmount);
(uint128 _amount0, uint128 _amount1) =
_pool.collectProtocol(_recipient, _amount0Requested, _amount1Requested);
// Protect the caller from receiving less than requested. See `collectProtocol` for context.
if (_amount0 < _amount0Requested || _amount1 < _amount1Requested) {
revert V3FactoryOwner__InsufficientFeesCollected();
}
emit FeesClaimed(address(_pool), msg.sender, _recipient, _amount0, _amount1);
return (_amount0, _amount1);
}
/// @notice Ensures the msg.sender is the contract admin and reverts otherwise.
/// @dev Place inside external methods to make them admin-only.
function _revertIfNotAdmin() internal view {
if (msg.sender != admin) revert V3FactoryOwner__Unauthorized();
}
}// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity ^0.8.23;
/// @title Permissioned pool actions
/// @notice Contains pool methods that may only be called by the factory owner
/// @dev Vendored from
/// https://github.com/Uniswap/v3-core/blob/d8b1c635c275d2a9450bd6a78f3fa2484fef73eb/contracts/interfaces/pool/IUniswapV3PoolOwnerActions.sol
interface IUniswapV3PoolOwnerActions {
/// @notice Set the denominator of the protocol's % share of the fees
/// @param feeProtocol0 new protocol fee for token0 of the pool
/// @param feeProtocol1 new protocol fee for token1 of the pool
function setFeeProtocol(uint8 feeProtocol0, uint8 feeProtocol1) external;
/// @notice Collect the protocol fee accrued to the pool
/// @param recipient The address to which collected protocol fees should be sent
/// @param amount0Requested The maximum amount of token0 to send, can be 0 to collect fees in only
/// token1
/// @param amount1Requested The maximum amount of token1 to send, can be 0 to collect fees in only
/// token0
/// @return amount0 The protocol fee collected in token0
/// @return amount1 The protocol fee collected in token1
function collectProtocol(address recipient, uint128 amount0Requested, uint128 amount1Requested)
external
returns (uint128 amount0, uint128 amount1);
}// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity ^0.8.23;
/// @title The interface for the Uniswap V3 Factory
/// @notice The Uniswap V3 Factory facilitates creation of Uniswap V3 pools and control over the
/// protocol fees
/// @dev Stripped down and renamed from:
/// https://github.com/Uniswap/v3-core/blob/d8b1c635c275d2a9450bd6a78f3fa2484fef73eb/contracts/interfaces/IUniswapV3Factory.sol
interface IUniswapV3FactoryOwnerActions {
/// @notice Returns the current owner of the factory
/// @dev Can be changed by the current owner via setOwner
/// @return The address of the factory owner
function owner() external view returns (address);
/// @notice Updates the owner of the factory
/// @dev Must be called by the current owner
/// @param _owner The new owner of the factory
function setOwner(address _owner) external;
/// @notice Enables a fee amount with the given tickSpacing
/// @dev Fee amounts may never be removed once enabled
/// @param fee The fee amount to enable, denominated in hundredths of a bip (i.e. 1e-6)
/// @param tickSpacing The spacing between ticks to be enforced for all pools created with the
/// given fee amount
function enableFeeAmount(uint24 fee, int24 tickSpacing) external;
/// @notice Returns the tick spacing for a given fee amount, if enabled, or 0 if not enabled
/// @dev A fee amount can never be removed, so this value should be hard coded or cached in the
/// calling context
/// @param fee The enabled fee, denominated in hundredths of a bip. Returns 0 in case of unenabled
/// fee
/// @return The tick spacing
function feeAmountTickSpacing(uint24 fee) external view returns (int24);
}// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity ^0.8.23;
/// @title INotifiableRewardReceiver
/// @author ScopeLift
/// @notice The communication interface between the V3FactoryOwner contract and the UniStaker
/// contract. In particular, the V3FactoryOwner only needs to know the latter implements the
/// specified method in order to forward payouts to the UniStaker contract. The UniStaker contract
/// receives the rewards and abstracts the distribution mechanics
interface INotifiableRewardReceiver {
/// @notice Method called to notify a reward receiver it has received a reward.
/// @param _amount The amount of reward.
function notifyRewardAmount(uint256 _amount) external;
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.20;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
/**
* @dev Returns the value of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the value of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves a `value` amount of tokens from the caller's account to `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, uint256 value) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets a `value` amount of tokens as the allowance of `spender` over the
* caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 value) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the
* allowance mechanism. `value` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address from, address to, uint256 value) external returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/utils/SafeERC20.sol)
pragma solidity ^0.8.20;
import {IERC20} from "../IERC20.sol";
import {IERC20Permit} from "../extensions/IERC20Permit.sol";
import {Address} from "../../../utils/Address.sol";
/**
* @title SafeERC20
* @dev Wrappers around ERC20 operations that throw on failure (when the token
* contract returns false). Tokens that return no value (and instead revert or
* throw on failure) are also supported, non-reverting calls are assumed to be
* successful.
* To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/
library SafeERC20 {
using Address for address;
/**
* @dev An operation with an ERC20 token failed.
*/
error SafeERC20FailedOperation(address token);
/**
* @dev Indicates a failed `decreaseAllowance` request.
*/
error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease);
/**
* @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeTransfer(IERC20 token, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeCall(token.transfer, (to, value)));
}
/**
* @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the
* calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.
*/
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeCall(token.transferFrom, (from, to, value)));
}
/**
* @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 oldAllowance = token.allowance(address(this), spender);
forceApprove(token, spender, oldAllowance + value);
}
/**
* @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no
* value, non-reverting calls are assumed to be successful.
*/
function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal {
unchecked {
uint256 currentAllowance = token.allowance(address(this), spender);
if (currentAllowance < requestedDecrease) {
revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease);
}
forceApprove(token, spender, currentAllowance - requestedDecrease);
}
}
/**
* @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval
* to be set to zero before setting it to a non-zero value, such as USDT.
*/
function forceApprove(IERC20 token, address spender, uint256 value) internal {
bytes memory approvalCall = abi.encodeCall(token.approve, (spender, value));
if (!_callOptionalReturnBool(token, approvalCall)) {
_callOptionalReturn(token, abi.encodeCall(token.approve, (spender, 0)));
_callOptionalReturn(token, approvalCall);
}
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*/
function _callOptionalReturn(IERC20 token, bytes memory data) private {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that
// the target address contains contract code and also asserts for success in the low-level call.
bytes memory returndata = address(token).functionCall(data);
if (returndata.length != 0 && !abi.decode(returndata, (bool))) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*
* This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.
*/
function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false
// and not revert is the subcall reverts.
(bool success, bytes memory returndata) = address(token).call(data);
return success && (returndata.length == 0 || abi.decode(returndata, (bool))) && address(token).code.length > 0;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Permit.sol)
pragma solidity ^0.8.20;
/**
* @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
* https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
*
* Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
* presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't
* need to send a transaction, and thus is not required to hold Ether at all.
*
* ==== Security Considerations
*
* There are two important considerations concerning the use of `permit`. The first is that a valid permit signature
* expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be
* considered as an intention to spend the allowance in any specific way. The second is that because permits have
* built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should
* take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be
* generally recommended is:
*
* ```solidity
* function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public {
* try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {}
* doThing(..., value);
* }
*
* function doThing(..., uint256 value) public {
* token.safeTransferFrom(msg.sender, address(this), value);
* ...
* }
* ```
*
* Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of
* `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also
* {SafeERC20-safeTransferFrom}).
*
* Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so
* contracts should have entry points that don't rely on permit.
*/
interface IERC20Permit {
/**
* @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
* given ``owner``'s signed approval.
*
* IMPORTANT: The same issues {IERC20-approve} has related to transaction
* ordering also apply here.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `spender` cannot be the zero address.
* - `deadline` must be a timestamp in the future.
* - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
* over the EIP712-formatted function arguments.
* - the signature must use ``owner``'s current nonce (see {nonces}).
*
* For more information on the signature format, see the
* https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
* section].
*
* CAUTION: See Security Considerations above.
*/
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
/**
* @dev Returns the current nonce for `owner`. This value must be
* included whenever a signature is generated for {permit}.
*
* Every successful call to {permit} increases ``owner``'s nonce by one. This
* prevents a signature from being used multiple times.
*/
function nonces(address owner) external view returns (uint256);
/**
* @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.
*/
// solhint-disable-next-line func-name-mixedcase
function DOMAIN_SEPARATOR() external view returns (bytes32);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/Address.sol)
pragma solidity ^0.8.20;
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev The ETH balance of the account is not enough to perform the operation.
*/
error AddressInsufficientBalance(address account);
/**
* @dev There's no code at `target` (it is not a contract).
*/
error AddressEmptyCode(address target);
/**
* @dev A call to an address target failed. The target may have reverted.
*/
error FailedInnerCall();
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.8.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
if (address(this).balance < amount) {
revert AddressInsufficientBalance(address(this));
}
(bool success, ) = recipient.call{value: amount}("");
if (!success) {
revert FailedInnerCall();
}
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain `call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason or custom error, it is bubbled
* up by this function (like regular Solidity function calls). However, if
* the call reverted with no returned reason, this function reverts with a
* {FailedInnerCall} error.
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*/
function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
if (address(this).balance < value) {
revert AddressInsufficientBalance(address(this));
}
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResultFromTarget(target, success, returndata);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResultFromTarget(target, success, returndata);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResultFromTarget(target, success, returndata);
}
/**
* @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target
* was not a contract or bubbling up the revert reason (falling back to {FailedInnerCall}) in case of an
* unsuccessful call.
*/
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata
) internal view returns (bytes memory) {
if (!success) {
_revert(returndata);
} else {
// only check if target is a contract if the call was successful and the return data is empty
// otherwise we already know that it was a contract
if (returndata.length == 0 && target.code.length == 0) {
revert AddressEmptyCode(target);
}
return returndata;
}
}
/**
* @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the
* revert reason or with a default {FailedInnerCall} error.
*/
function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) {
if (!success) {
_revert(returndata);
} else {
return returndata;
}
}
/**
* @dev Reverts with returndata if present. Otherwise reverts with {FailedInnerCall}.
*/
function _revert(bytes memory returndata) private pure {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
/// @solidity memory-safe-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert FailedInnerCall();
}
}
}{
"remappings": [
"openzeppelin/=lib/openzeppelin-contracts/contracts/",
"uniswap-periphery/=lib/v3-periphery/contracts/",
"@uniswap/v3-core/=lib/v3-core/",
"@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
"ds-test/=lib/forge-std/lib/ds-test/src/",
"erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/",
"forge-std/=lib/forge-std/src/",
"openzeppelin-contracts/=lib/openzeppelin-contracts/",
"v3-core/=lib/v3-core/",
"v3-periphery/=lib/v3-periphery/contracts/"
],
"optimizer": {
"enabled": true,
"runs": 10000000
},
"metadata": {
"useLiteralContent": false,
"bytecodeHash": "ipfs",
"appendCBOR": true
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"abi"
]
}
},
"evmVersion": "paris",
"viaIR": false,
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_admin","type":"address"},{"internalType":"contract IUniswapV3FactoryOwnerActions","name":"_factory","type":"address"},{"internalType":"contract IERC20","name":"_payoutToken","type":"address"},{"internalType":"uint256","name":"_payoutAmount","type":"uint256"},{"internalType":"contract INotifiableRewardReceiver","name":"_rewardReceiver","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"target","type":"address"}],"name":"AddressEmptyCode","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"AddressInsufficientBalance","type":"error"},{"inputs":[],"name":"FailedInnerCall","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"SafeERC20FailedOperation","type":"error"},{"inputs":[],"name":"V3FactoryOwner__InsufficientFeesCollected","type":"error"},{"inputs":[],"name":"V3FactoryOwner__InvalidAddress","type":"error"},{"inputs":[],"name":"V3FactoryOwner__InvalidPayoutAmount","type":"error"},{"inputs":[],"name":"V3FactoryOwner__Unauthorized","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldAmin","type":"address"},{"indexed":true,"internalType":"address","name":"newAdmin","type":"address"}],"name":"AdminSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pool","type":"address"},{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount0","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount1","type":"uint256"}],"name":"FeesClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"oldPayoutAmount","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"newPayoutAmount","type":"uint256"}],"name":"PayoutAmountSet","type":"event"},{"inputs":[],"name":"FACTORY","outputs":[{"internalType":"contract IUniswapV3FactoryOwnerActions","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PAYOUT_TOKEN","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"REWARD_RECEIVER","outputs":[{"internalType":"contract INotifiableRewardReceiver","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"admin","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IUniswapV3PoolOwnerActions","name":"_pool","type":"address"},{"internalType":"address","name":"_recipient","type":"address"},{"internalType":"uint128","name":"_amount0Requested","type":"uint128"},{"internalType":"uint128","name":"_amount1Requested","type":"uint128"}],"name":"claimFees","outputs":[{"internalType":"uint128","name":"","type":"uint128"},{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint24","name":"_fee","type":"uint24"},{"internalType":"int24","name":"_tickSpacing","type":"int24"}],"name":"enableFeeAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"payoutAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_newAdmin","type":"address"}],"name":"setAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IUniswapV3PoolOwnerActions","name":"_pool","type":"address"},{"internalType":"uint8","name":"_feeProtocol0","type":"uint8"},{"internalType":"uint8","name":"_feeProtocol1","type":"uint8"}],"name":"setFeeProtocol","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newPayoutAmount","type":"uint256"}],"name":"setPayoutAmount","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
60e060405234801561001057600080fd5b50604051610edf380380610edf83398101604081905261002f91610127565b6001600160a01b0385166100565760405163a553972760e01b815260040160405180910390fd5b816000036100775760405163b4230b9d60e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b0387811691821790925585821660805284821660a052600084815591831660c0526040519091907fbf265e8326285a2747e33e54d5945f7111f2b5edb826eb8c08d4677779b3ff97908290a360405182906000907f8f6c5c01f9385e42ed275713f18de607d67ea7f6673e431418c8b286057a2207908290a35050505050610192565b6001600160a01b038116811461012457600080fd5b50565b600080600080600060a0868803121561013f57600080fd5b855161014a8161010f565b602087015190955061015b8161010f565b604087015190945061016c8161010f565b6060870151608088015191945092506101848161010f565b809150509295509295909350565b60805160a05160c051610d036101dc6000396000818161017e015281816104d3015261056f0152600081816101e101526104f701526000818160c801526104550152610d036000f3fe608060405234801561001057600080fd5b50600436106100be5760003560e01c80638a7c195f11610076578063bf2d5f1b1161005b578063bf2d5f1b146101a0578063e2f6f511146101dc578063f851a4401461020357600080fd5b80638a7c195f14610166578063a508ff6c1461017957600080fd5b80636b46c8c3116100a75780636b46c8c314610129578063704b6c02146101405780637f4d39451461015357600080fd5b80632dd31000146100c357806336077b3c14610114575b600080fd5b6100ea7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b610127610122366004610b10565b610223565b005b61013260005481565b60405190815260200161010b565b61012761014e366004610b55565b6102ba565b610127610161366004610b72565b61039d565b610127610174366004610b8b565b610410565b6100ea7f000000000000000000000000000000000000000000000000000000000000000081565b6101b36101ae366004610bf1565b6104ca565b604080516fffffffffffffffffffffffffffffffff93841681529290911660208301520161010b565b6100ea7f000000000000000000000000000000000000000000000000000000000000000081565b6001546100ea9073ffffffffffffffffffffffffffffffffffffffff1681565b61022b61079e565b6040517f8206a4d100000000000000000000000000000000000000000000000000000000815260ff80841660048301528216602482015273ffffffffffffffffffffffffffffffffffffffff841690638206a4d190604401600060405180830381600087803b15801561029d57600080fd5b505af11580156102b1573d6000803e3d6000fd5b50505050505050565b6102c261079e565b73ffffffffffffffffffffffffffffffffffffffff811661030f576040517fa553972700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60015460405173ffffffffffffffffffffffffffffffffffffffff8084169216907fbf265e8326285a2747e33e54d5945f7111f2b5edb826eb8c08d4677779b3ff9790600090a3600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b6103a561079e565b806000036103df576040517fb4230b9d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805460405183927f8f6c5c01f9385e42ed275713f18de607d67ea7f6673e431418c8b286057a220791a3600055565b61041861079e565b6040517f8a7c195f00000000000000000000000000000000000000000000000000000000815262ffffff83166004820152600282900b60248201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690638a7c195f90604401600060405180830381600087803b1580156104ae57600080fd5b505af11580156104c2573d6000803e3d6000fd5b505050505050565b60008061053c337f00000000000000000000000000000000000000000000000000000000000000006000547f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166107f1909392919063ffffffff16565b6000546040517f3c6b16ab00000000000000000000000000000000000000000000000000000000815260048101919091527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690633c6b16ab90602401600060405180830381600087803b1580156105c857600080fd5b505af11580156105dc573d6000803e3d6000fd5b50506040517f85b6672900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff88811660048301526fffffffffffffffffffffffffffffffff808916602484015287166044830152600093508392508916906385b667299060640160408051808303816000875af1158015610672573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106969190610c4d565b91509150856fffffffffffffffffffffffffffffffff16826fffffffffffffffffffffffffffffffff1610806106ef5750846fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff16105b15610726576040517f0790df8600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516fffffffffffffffffffffffffffffffff80851682528316602082015273ffffffffffffffffffffffffffffffffffffffff808a16923392918c16917fd377f58cbc83f844989775f0d4bfa247dbee70bf3d851b8c5f0e0fe51d3b6ef9910160405180910390a49097909650945050505050565b60015473ffffffffffffffffffffffffffffffffffffffff1633146107ef576040517fd064e4bd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b6040805173ffffffffffffffffffffffffffffffffffffffff85811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd0000000000000000000000000000000000000000000000000000000017905261088690859061088c565b50505050565b60006108ae73ffffffffffffffffffffffffffffffffffffffff84168361092c565b905080516000141580156108d35750808060200190518101906108d19190610c7c565b155b15610927576040517f5274afe700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff841660048201526024015b60405180910390fd5b505050565b606061093a83836000610941565b9392505050565b60608147101561097f576040517fcd78605900000000000000000000000000000000000000000000000000000000815230600482015260240161091e565b6000808573ffffffffffffffffffffffffffffffffffffffff1684866040516109a89190610c9e565b60006040518083038185875af1925050503d80600081146109e5576040519150601f19603f3d011682016040523d82523d6000602084013e6109ea565b606091505b50915091506109fa868383610a04565b9695505050505050565b606082610a1957610a1482610a93565b61093a565b8151158015610a3d575073ffffffffffffffffffffffffffffffffffffffff84163b155b15610a8c576040517f9996b31500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8516600482015260240161091e565b508061093a565b805115610aa35780518082602001fd5b6040517f1425ea4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50565b73ffffffffffffffffffffffffffffffffffffffff81168114610ad557600080fd5b803560ff81168114610b0b57600080fd5b919050565b600080600060608486031215610b2557600080fd5b8335610b3081610ad8565b9250610b3e60208501610afa565b9150610b4c60408501610afa565b90509250925092565b600060208284031215610b6757600080fd5b813561093a81610ad8565b600060208284031215610b8457600080fd5b5035919050565b60008060408385031215610b9e57600080fd5b823562ffffff81168114610bb157600080fd5b91506020830135600281900b8114610bc857600080fd5b809150509250929050565b6fffffffffffffffffffffffffffffffff81168114610ad557600080fd5b60008060008060808587031215610c0757600080fd5b8435610c1281610ad8565b93506020850135610c2281610ad8565b92506040850135610c3281610bd3565b91506060850135610c4281610bd3565b939692955090935050565b60008060408385031215610c6057600080fd5b8251610c6b81610bd3565b6020840151909250610bc881610bd3565b600060208284031215610c8e57600080fd5b8151801515811461093a57600080fd5b6000825160005b81811015610cbf5760208186018101518583015201610ca5565b50600092019182525091905056fea264697066735822122008a6b35575393a510061efd1eae133068932958d79f59515eea9f79583b84b1f64736f6c634300081700330000000000000000000000001a9c8182c09f50c8318d769245bea52c32be35bc0000000000000000000000001f98431c8ad98523631ae4a59f267346ea31f984000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000008ac7230489e80000000000000000000000000000e3071e87a7e6dd19a911dbf1127ba9dd67aa6fc8
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106100be5760003560e01c80638a7c195f11610076578063bf2d5f1b1161005b578063bf2d5f1b146101a0578063e2f6f511146101dc578063f851a4401461020357600080fd5b80638a7c195f14610166578063a508ff6c1461017957600080fd5b80636b46c8c3116100a75780636b46c8c314610129578063704b6c02146101405780637f4d39451461015357600080fd5b80632dd31000146100c357806336077b3c14610114575b600080fd5b6100ea7f0000000000000000000000001f98431c8ad98523631ae4a59f267346ea31f98481565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b610127610122366004610b10565b610223565b005b61013260005481565b60405190815260200161010b565b61012761014e366004610b55565b6102ba565b610127610161366004610b72565b61039d565b610127610174366004610b8b565b610410565b6100ea7f000000000000000000000000e3071e87a7e6dd19a911dbf1127ba9dd67aa6fc881565b6101b36101ae366004610bf1565b6104ca565b604080516fffffffffffffffffffffffffffffffff93841681529290911660208301520161010b565b6100ea7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b6001546100ea9073ffffffffffffffffffffffffffffffffffffffff1681565b61022b61079e565b6040517f8206a4d100000000000000000000000000000000000000000000000000000000815260ff80841660048301528216602482015273ffffffffffffffffffffffffffffffffffffffff841690638206a4d190604401600060405180830381600087803b15801561029d57600080fd5b505af11580156102b1573d6000803e3d6000fd5b50505050505050565b6102c261079e565b73ffffffffffffffffffffffffffffffffffffffff811661030f576040517fa553972700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60015460405173ffffffffffffffffffffffffffffffffffffffff8084169216907fbf265e8326285a2747e33e54d5945f7111f2b5edb826eb8c08d4677779b3ff9790600090a3600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b6103a561079e565b806000036103df576040517fb4230b9d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805460405183927f8f6c5c01f9385e42ed275713f18de607d67ea7f6673e431418c8b286057a220791a3600055565b61041861079e565b6040517f8a7c195f00000000000000000000000000000000000000000000000000000000815262ffffff83166004820152600282900b60248201527f0000000000000000000000001f98431c8ad98523631ae4a59f267346ea31f98473ffffffffffffffffffffffffffffffffffffffff1690638a7c195f90604401600060405180830381600087803b1580156104ae57600080fd5b505af11580156104c2573d6000803e3d6000fd5b505050505050565b60008061053c337f000000000000000000000000e3071e87a7e6dd19a911dbf1127ba9dd67aa6fc86000547f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc273ffffffffffffffffffffffffffffffffffffffff166107f1909392919063ffffffff16565b6000546040517f3c6b16ab00000000000000000000000000000000000000000000000000000000815260048101919091527f000000000000000000000000e3071e87a7e6dd19a911dbf1127ba9dd67aa6fc873ffffffffffffffffffffffffffffffffffffffff1690633c6b16ab90602401600060405180830381600087803b1580156105c857600080fd5b505af11580156105dc573d6000803e3d6000fd5b50506040517f85b6672900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff88811660048301526fffffffffffffffffffffffffffffffff808916602484015287166044830152600093508392508916906385b667299060640160408051808303816000875af1158015610672573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106969190610c4d565b91509150856fffffffffffffffffffffffffffffffff16826fffffffffffffffffffffffffffffffff1610806106ef5750846fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff16105b15610726576040517f0790df8600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516fffffffffffffffffffffffffffffffff80851682528316602082015273ffffffffffffffffffffffffffffffffffffffff808a16923392918c16917fd377f58cbc83f844989775f0d4bfa247dbee70bf3d851b8c5f0e0fe51d3b6ef9910160405180910390a49097909650945050505050565b60015473ffffffffffffffffffffffffffffffffffffffff1633146107ef576040517fd064e4bd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b6040805173ffffffffffffffffffffffffffffffffffffffff85811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd0000000000000000000000000000000000000000000000000000000017905261088690859061088c565b50505050565b60006108ae73ffffffffffffffffffffffffffffffffffffffff84168361092c565b905080516000141580156108d35750808060200190518101906108d19190610c7c565b155b15610927576040517f5274afe700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff841660048201526024015b60405180910390fd5b505050565b606061093a83836000610941565b9392505050565b60608147101561097f576040517fcd78605900000000000000000000000000000000000000000000000000000000815230600482015260240161091e565b6000808573ffffffffffffffffffffffffffffffffffffffff1684866040516109a89190610c9e565b60006040518083038185875af1925050503d80600081146109e5576040519150601f19603f3d011682016040523d82523d6000602084013e6109ea565b606091505b50915091506109fa868383610a04565b9695505050505050565b606082610a1957610a1482610a93565b61093a565b8151158015610a3d575073ffffffffffffffffffffffffffffffffffffffff84163b155b15610a8c576040517f9996b31500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8516600482015260240161091e565b508061093a565b805115610aa35780518082602001fd5b6040517f1425ea4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50565b73ffffffffffffffffffffffffffffffffffffffff81168114610ad557600080fd5b803560ff81168114610b0b57600080fd5b919050565b600080600060608486031215610b2557600080fd5b8335610b3081610ad8565b9250610b3e60208501610afa565b9150610b4c60408501610afa565b90509250925092565b600060208284031215610b6757600080fd5b813561093a81610ad8565b600060208284031215610b8457600080fd5b5035919050565b60008060408385031215610b9e57600080fd5b823562ffffff81168114610bb157600080fd5b91506020830135600281900b8114610bc857600080fd5b809150509250929050565b6fffffffffffffffffffffffffffffffff81168114610ad557600080fd5b60008060008060808587031215610c0757600080fd5b8435610c1281610ad8565b93506020850135610c2281610ad8565b92506040850135610c3281610bd3565b91506060850135610c4281610bd3565b939692955090935050565b60008060408385031215610c6057600080fd5b8251610c6b81610bd3565b6020840151909250610bc881610bd3565b600060208284031215610c8e57600080fd5b8151801515811461093a57600080fd5b6000825160005b81811015610cbf5760208186018101518583015201610ca5565b50600092019182525091905056fea264697066735822122008a6b35575393a510061efd1eae133068932958d79f59515eea9f79583b84b1f64736f6c63430008170033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000001a9c8182c09f50c8318d769245bea52c32be35bc0000000000000000000000001f98431c8ad98523631ae4a59f267346ea31f984000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000008ac7230489e80000000000000000000000000000e3071e87a7e6dd19a911dbf1127ba9dd67aa6fc8
-----Decoded View---------------
Arg [0] : _admin (address): 0x1a9C8182C09F50C8318d769245beA52c32BE35BC
Arg [1] : _factory (address): 0x1F98431c8aD98523631AE4a59f267346ea31F984
Arg [2] : _payoutToken (address): 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2
Arg [3] : _payoutAmount (uint256): 10000000000000000000
Arg [4] : _rewardReceiver (address): 0xE3071e87a7E6dD19A911Dbf1127BA9dD67Aa6fc8
-----Encoded View---------------
5 Constructor Arguments found :
Arg [0] : 0000000000000000000000001a9c8182c09f50c8318d769245bea52c32be35bc
Arg [1] : 0000000000000000000000001f98431c8ad98523631ae4a59f267346ea31f984
Arg [2] : 000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2
Arg [3] : 0000000000000000000000000000000000000000000000008ac7230489e80000
Arg [4] : 000000000000000000000000e3071e87a7e6dd19a911dbf1127ba9dd67aa6fc8
Deployed Bytecode Sourcemap
1865:9601:4:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3417:54;;;;;;;;228:42:8;216:55;;;198:74;;186:2;171:18;3417:54:4;;;;;;;;6843:211;;;;;;:::i;:::-;;:::i;:::-;;3706:27;;;;;;;;;1232:25:8;;;1220:2;1205:18;3706:27:4;1086:177:8;5286:210:4;;;;;;:::i;:::-;;:::i;5656:262::-;;;;;;:::i;:::-;;:::i;6262:146::-;;;;;;:::i;:::-;;:::i;3857:58::-;;;;;10396:800;;;;;;:::i;:::-;;:::i;:::-;;;;3547:34:8;3608:15;;;3590:34;;3660:15;;;;3655:2;3640:18;;3633:43;3510:18;10396:800:4;3363:319:8;3567:36:4;;;;;4047:20;;;;;;;;;6843:211;6974:19;:17;:19::i;:::-;6999:50;;;;;4358:4:8;4346:17;;;6999:50:4;;;4328:36:8;4400:17;;4380:18;;;4373:45;6999:20:4;;;;;;4301:18:8;;6999:50:4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6843:211;;;:::o;5286:210::-;5338:19;:17;:19::i;:::-;5367:23;;;5363:68;;5399:32;;;;;;;;;;;;;;5363:68;5451:5;;5442:26;;;;;;;5451:5;;5442:26;;5451:5;;5442:26;5474:5;:17;;;;;;;;;;;;;;;5286:210::o;5656:262::-;5722:19;:17;:19::i;:::-;5751:16;5771:1;5751:21;5747:71;;5781:37;;;;;;;;;;;;;;5747:71;5845:12;;;5829:47;;5859:16;;5829:47;;;5882:12;:31;5656:262::o;6262:146::-;6335:19;:17;:19::i;:::-;6360:43;;;;;4627:8:8;4615:21;;6360:43:4;;;4597:40:8;4684:1;4673:21;;;4653:18;;;4646:49;6360:7:4;:23;;;;;4570:18:8;;6360:43:4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6262:146;;:::o;10396:800::-;10561:7;10570;10585:81;10615:10;10635:15;10653:12;;10585;:29;;;;:81;;;;;;:::i;:::-;10707:12;;10672:48;;;;;;;;1232:25:8;;;;10672:15:4;:34;;;;;1205:18:8;;10672:48:4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;10771:71:4;;;;;:21;4926:55:8;;;10771:71:4;;;4908:74:8;5001:34;5071:15;;;5051:18;;;5044:43;5123:15;;5103:18;;;5096:43;10727:16:4;;-1:-1:-1;10727:16:4;;-1:-1:-1;10771:21:4;;;;;4881:18:8;;10771:71:4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;10726:116;;;;10961:17;10950:28;;:8;:28;;;:60;;;;10993:17;10982:28;;:8;:28;;;10950:60;10946:131;;;11027:43;;;;;;;;;;;;;;10946:131;11087:71;;;3547:34:8;3608:15;;;3590:34;;3660:15;;3655:2;3640:18;;3633:43;11087:71:4;;;;;11115:10;;11087:71;;;;;;3510:18:8;11087:71:4;;;;;;;11172:8;;;;-1:-1:-1;10396:800:4;-1:-1:-1;;;;;10396:800:4:o;11348:116::-;11415:5;;;;11401:10;:19;11397:62;;11429:30;;;;;;;;;;;;;;11397:62;11348:116::o;1702:188:2:-;1829:53;;;1844:18;6145:15:8;;;1829:53:2;;;6127:34:8;6197:15;;6177:18;;;6170:43;6229:18;;;;6222:34;;;1829:53:2;;;;;;;;;;6039:18:8;;;;1829:53:2;;;;;;;;;;;;;;1802:81;;1822:5;;1802:19;:81::i;:::-;1702:188;;;;:::o;4059:629::-;4478:23;4504:33;:27;;;4532:4;4504:27;:33::i;:::-;4478:59;;4551:10;:17;4572:1;4551:22;;:57;;;;;4589:10;4578:30;;;;;;;;;;;;:::i;:::-;4577:31;4551:57;4547:135;;;4631:40;;;;;228:42:8;216:55;;4631:40:2;;;198:74:8;171:18;;4631:40:2;;;;;;;;4547:135;4129:559;4059:629;;:::o;2705:151:3:-;2780:12;2811:38;2833:6;2841:4;2847:1;2811:21;:38::i;:::-;2804:45;2705:151;-1:-1:-1;;;2705:151:3:o;3180:392::-;3279:12;3331:5;3307:21;:29;3303:108;;;3359:41;;;;;3394:4;3359:41;;;198:74:8;171:18;;3359:41:3;14:264:8;3303:108:3;3421:12;3435:23;3462:6;:11;;3481:5;3488:4;3462:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3420:73;;;;3510:55;3537:6;3545:7;3554:10;3510:26;:55::i;:::-;3503:62;3180:392;-1:-1:-1;;;;;;3180:392:3:o;4625:582::-;4769:12;4798:7;4793:408;;4821:19;4829:10;4821:7;:19::i;:::-;4793:408;;;5045:17;;:22;:49;;;;-1:-1:-1;5071:18:3;;;;:23;5045:49;5041:119;;;5121:24;;;;;228:42:8;216:55;;5121:24:3;;;198:74:8;171:18;;5121:24:3;14:264:8;5041:119:3;-1:-1:-1;5180:10:3;5173:17;;5743:516;5874:17;;:21;5870:383;;6102:10;6096:17;6158:15;6145:10;6141:2;6137:19;6130:44;5870:383;6225:17;;;;;;;;;;;;;;5870:383;5743:516;:::o;283:182:8:-;397:42;390:5;386:54;379:5;376:65;366:93;;455:1;452;445:12;470:156;536:20;;596:4;585:16;;575:27;;565:55;;616:1;613;606:12;565:55;470:156;;;:::o;631:450::-;739:6;747;755;808:2;796:9;787:7;783:23;779:32;776:52;;;824:1;821;814:12;776:52;863:9;850:23;882:59;935:5;882:59;:::i;:::-;960:5;-1:-1:-1;984:36:8;1016:2;1001:18;;984:36;:::i;:::-;974:46;;1039:36;1071:2;1060:9;1056:18;1039:36;:::i;:::-;1029:46;;631:450;;;;;:::o;1268:275::-;1327:6;1380:2;1368:9;1359:7;1355:23;1351:32;1348:52;;;1396:1;1393;1386:12;1348:52;1435:9;1422:23;1454:59;1507:5;1454:59;:::i;1548:180::-;1607:6;1660:2;1648:9;1639:7;1635:23;1631:32;1628:52;;;1676:1;1673;1666:12;1628:52;-1:-1:-1;1699:23:8;;1548:180;-1:-1:-1;1548:180:8:o;1733:443::-;1798:6;1806;1859:2;1847:9;1838:7;1834:23;1830:32;1827:52;;;1875:1;1872;1865:12;1827:52;1914:9;1901:23;1964:8;1957:5;1953:20;1946:5;1943:31;1933:59;;1988:1;1985;1978:12;1933:59;2011:5;-1:-1:-1;2068:2:8;2053:18;;2040:32;2114:1;2103:22;;;2091:35;;2081:63;;2140:1;2137;2130:12;2081:63;2163:7;2153:17;;;1733:443;;;;;:::o;2445:146::-;2531:34;2524:5;2520:46;2513:5;2510:57;2500:85;;2581:1;2578;2571:12;2596:762;2717:6;2725;2733;2741;2794:3;2782:9;2773:7;2769:23;2765:33;2762:53;;;2811:1;2808;2801:12;2762:53;2850:9;2837:23;2869:59;2922:5;2869:59;:::i;:::-;2947:5;-1:-1:-1;3004:2:8;2989:18;;2976:32;3017:61;2976:32;3017:61;:::i;:::-;3097:7;-1:-1:-1;3156:2:8;3141:18;;3128:32;3169:33;3128:32;3169:33;:::i;:::-;3221:7;-1:-1:-1;3280:2:8;3265:18;;3252:32;3293:33;3252:32;3293:33;:::i;:::-;2596:762;;;;-1:-1:-1;2596:762:8;;-1:-1:-1;;2596:762:8:o;5150:385::-;5229:6;5237;5290:2;5278:9;5269:7;5265:23;5261:32;5258:52;;;5306:1;5303;5296:12;5258:52;5338:9;5332:16;5357:31;5382:5;5357:31;:::i;:::-;5457:2;5442:18;;5436:25;5407:5;;-1:-1:-1;5470:33:8;5436:25;5470:33;:::i;6267:277::-;6334:6;6387:2;6375:9;6366:7;6362:23;6358:32;6355:52;;;6403:1;6400;6393:12;6355:52;6435:9;6429:16;6488:5;6481:13;6474:21;6467:5;6464:32;6454:60;;6510:1;6507;6500:12;6549:412;6678:3;6716:6;6710:13;6741:1;6751:129;6765:6;6762:1;6759:13;6751:129;;;6863:4;6847:14;;;6843:25;;6837:32;6824:11;;;6817:53;6780:12;6751:129;;;-1:-1:-1;6935:1:8;6899:16;;6924:13;;;-1:-1:-1;6899:16:8;6549:412;-1:-1:-1;6549:412:8:o
Swarm Source
ipfs://08a6b35575393a510061efd1eae133068932958d79f59515eea9f79583b84b1f
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 34 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
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.