Polygon Sponsored slots available. Book your slot here!
More Info
Private Name Tags
ContractCreator
Latest 14 from a total of 14 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Create Rewards P... | 58031626 | 174 days ago | IN | 0 POL | 0.0036498 | ||||
Create Rewards P... | 57688897 | 183 days ago | IN | 0 POL | 0.00365052 | ||||
Create Rewards P... | 57688806 | 183 days ago | IN | 0 POL | 0.00433281 | ||||
Create Rewards P... | 57263946 | 194 days ago | IN | 0 POL | 0.010367 | ||||
Create Rewards P... | 56573649 | 212 days ago | IN | 0 POL | 0.00374259 | ||||
Create Rewards P... | 56400352 | 217 days ago | IN | 0 POL | 0.00535636 | ||||
Create Rewards P... | 56130673 | 224 days ago | IN | 0 POL | 0.00632912 | ||||
Create Rewards P... | 56118341 | 224 days ago | IN | 0 POL | 0.01811515 | ||||
Create Rewards P... | 56069301 | 226 days ago | IN | 0 POL | 0.00710835 | ||||
Create Rewards P... | 55987128 | 228 days ago | IN | 0 POL | 0.01278543 | ||||
Create Rewards P... | 55143276 | 250 days ago | IN | 0 POL | 0.05116012 | ||||
Set Module Metad... | 55106993 | 251 days ago | IN | 0 POL | 0.0158544 | ||||
Set Module Metad... | 55106039 | 251 days ago | IN | 0 POL | 0.0158544 | ||||
Set Module Metad... | 55106039 | 251 days ago | IN | 0 POL | 0.0458956 |
Loading...
Loading
Contract Name:
RewardsSwap
Compiler Version
v0.8.21+commit.d9974bed
Optimization Enabled:
Yes with 2000 runs
Other Settings:
london EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT /* __/\\\\____________/\\\\_____/\\\\\\\\\_____/\\\\\\\\\\\\_____/\\\\\\\\\\\\\\\__/\\\\\\\\\\\_ _\/\\\\\\________/\\\\\\___/\\\\\\\\\\\\\__\/\\\////////\\\__\/\\\///////////__\/////\\\///__ _\/\\\//\\\____/\\\//\\\__/\\\/////////\\\_\/\\\______\//\\\_\/\\\_________________\/\\\_____ _\/\\\\///\\\/\\\/_\/\\\_\/\\\_______\/\\\_\/\\\_______\/\\\_\/\\\\\\\\\\\_________\/\\\_____ _\/\\\__\///\\\/___\/\\\_\/\\\\\\\\\\\\\\\_\/\\\_______\/\\\_\/\\\///////__________\/\\\_____ _\/\\\____\///_____\/\\\_\/\\\/////////\\\_\/\\\_______\/\\\_\/\\\_________________\/\\\_____ _\/\\\_____________\/\\\_\/\\\_______\/\\\_\/\\\_______/\\\__\/\\\_________________\/\\\_____ _\/\\\_____________\/\\\_\/\\\_______\/\\\_\/\\\\\\\\\\\\/___\/\\\______________/\\\\\\\\\\\_ _\///______________\///__\///________\///__\////////////_____\///______________\///////////__ */ pragma solidity ^0.8.13; import {IPublicationActionModule, Types} from "lens/interfaces/IPublicationActionModule.sol"; import {HubRestricted} from "lens/base/HubRestricted.sol"; import {LensModuleMetadataInitializable} from 'lens/modules/LensModuleMetadataInitializable.sol'; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import {ISwapRouter} from "madfi-protocol/interfaces/IUniswap.sol"; import {IMadSBT} from "madfi-protocol/interfaces/IMadSBT.sol"; import {ILensHub} from "lens/interfaces/ILensHub.sol"; /** * @title RewardsSwap * @notice This is a contract for creating rewards pools for buying tokens and distributing * rewards to the owner of the publication that the action is being executed on. * * @dev First someone creates a rewards pool by depositing tokens and setting the parameters. * Then someone creates a post and sets the rewards pool ID. * Then someone calls processPublicationAction with the actionModuleData set to the swap path. * Alternatively you can set the rewardsPoolId to 0 and the token to the token you want to promote. */ contract RewardsSwap is IPublicationActionModule, HubRestricted, LensModuleMetadataInitializable { ISwapRouter public uniswapV3Router; IMadSBT public madSBT; ILensHub public hub; struct RewardsPool { uint256 rewardsAmount; // total amount of rewards to distribute uint16 percentReward; // percent of each swap to distribute as rewards bps i.e. 1000 = 10% address token; // token to swap for and distribute rewards for uint256 cap; // max amount of rewards to distribute per tx uint256 collectionId; // MadFi social club collection ID to award points on } struct Post { address recipient; uint256 rewardsPoolId; uint16 sharedRewardPercent; address token; // Optional, used if rewardsPoolId is not set } uint8 public constant PROTOCOL_FEE = 25; // 0.25% uint8 public constant DIRECT_PROMOTION_SPLIT = 25; // 0.25% uint16 public constant CLIENT_PERCENT = 5_00; // 5% mapping(address => uint256) public feesCollected; uint256 public poolCount; mapping(uint256 => RewardsPool) public rewardsPools; mapping(uint256 => mapping(uint256 => Post)) public posts; // profileId => pubId => Post event RewardsPoolCreated( uint256 indexed rewardsPoolId, address indexed token, uint256 rewardsAmount, uint16 percentReward, uint256 cap, uint256 collectionId ); event PublicationActionInitialized(uint256 indexed profileId, uint256 indexed pubId, uint256 rewardsPoolId); event RewardsPaid( uint256 rewardsPoolId, uint256 amountOut, uint256 sharedReward, uint256 posterReward, uint256 referrerReward, uint256 clientReward ); event FeesWithdrawn(address indexed token, address indexed to); error InvalidPercentReward(uint16 percentReward); error InvalidPercentCap(uint16 percentCap); error InvalidRewardsPoolId(uint256 rewardsPoolId); error BadOutputToken(address token); constructor( address _uniswapV3Router, address _madSBT, address _hub ) HubRestricted(_hub) LensModuleMetadataInitializable(msg.sender) { uniswapV3Router = ISwapRouter(_uniswapV3Router); madSBT = IMadSBT(_madSBT); hub = ILensHub(_hub); } /** * @notice Required by Lens Protocol */ function supportsInterface(bytes4 interfaceID) public pure override returns (bool) { return interfaceID == type(IPublicationActionModule).interfaceId || super.supportsInterface(interfaceID); } /** * @notice Creates a rewards pool for a given token. * @param token The token to swap for and distribute rewards for. * @param rewardsAmount The total amount of rewards to bew distributed. * @param percentReward The percent of each swap to distribute as rewards bps i.e. 1000 = 10%. * @param percentCap The max amount of rewards to distribute per tx, as a percent of the total rewards amount. * Direct amount is calculated as percent of rewardsAmount and stored as a uint256. * * @return uint256 The ID of the rewards pool. */ function createRewardsPool( address token, uint256 rewardsAmount, uint16 percentReward, uint16 percentCap, uint256 profileId ) external returns (uint256) { if (percentReward > 100_00) { revert InvalidPercentReward(percentReward); } if (percentCap > 100_00) { revert InvalidPercentCap(percentCap); } uint256 capAmount = rewardsAmount * percentCap / 100_00; uint256 collectionId = profileId == 0 ? 0 : madSBT.activeCollection(profileId); rewardsPools[++poolCount] = RewardsPool(rewardsAmount, percentReward, token, capAmount, collectionId); IERC20(token).transferFrom(msg.sender, address(this), rewardsAmount); emit RewardsPoolCreated(poolCount, token, rewardsAmount, percentReward, capAmount, collectionId); return poolCount; } /** * @notice Initializes the action module for the given publication being published with this Action module. * @custom:permissions LensHub. * * @param profileId The profile ID of the author publishing the content with this Publication Action. * @param pubId The publication ID being published. * @param data Arbitrary data passed from the user to be decoded by the Action Module during initialization. * * @return bytes Any custom ABI-encoded data. This will be a LensHub event params that can be used by * indexers or UIs. */ function initializePublicationAction(uint256 profileId, uint256 pubId, address, bytes calldata data) external onlyHub returns (bytes memory) { // Decode data to check if it's a pool-based or direct token promotion // Example: (bool isDirectPromotion, uint16 sharedRewardPercent, address recipient, uint256 rewardsPoolId, address token, uint256 feePercent) (bool isDirectPromotion, uint16 sharedRewardPercent, address recipient, uint256 rewardsPoolId, address token) = abi.decode(data, (bool, uint16, address, uint256, address)); if (sharedRewardPercent > 100_00) { revert InvalidPercentReward(sharedRewardPercent); } if (!isDirectPromotion && (rewardsPoolId > poolCount || rewardsPoolId == 0)) { revert InvalidRewardsPoolId(rewardsPoolId); } if (isDirectPromotion) { // Initialize post for direct token promotion posts[profileId][pubId] = Post(recipient, 0, sharedRewardPercent, token); } else { // Initialize post for rewards pool posts[profileId][pubId] = Post(recipient, rewardsPoolId, sharedRewardPercent, address(0)); } emit PublicationActionInitialized(profileId, pubId, rewardsPoolId); return ""; } /** * @notice Processes the action for a given publication. This includes the action's logic and any monetary/token * operations. * @custom:permissions LensHub. * * @param processActionParams The parameters needed to execute the publication action. * * @return bytes Any custom ABI-encoded data. This will be a LensHub event params that can be used by * indexers or UIs. */ function processPublicationAction(Types.ProcessActionParams calldata processActionParams) external onlyHub returns (bytes memory) { // Get the post data Post memory post = posts[processActionParams.publicationActedProfileId][processActionParams.publicationActedId]; // Get rewards pool and action data RewardsPool memory rewardsPool = rewardsPools[post.rewardsPoolId]; // Decode the actionModuleData to include a path for multi-hop swaps (bytes memory path, uint256 deadline, uint256 amountIn, uint256 amountOutMinimum, address clientAddress) = abi.decode(processActionParams.actionModuleData, (bytes, uint256, uint256, uint256, address)); // Extract the final token in the path address finalTokenInPath = extractFinalTokenAddress(path); // Determine the expected final token based on the post type (rewards pool or direct promotion) address expectedFinalToken = post.token != address(0) ? post.token : rewardsPool.token; // Verify the final token in the path matches the expected token if (finalTokenInPath != expectedFinalToken) revert BadOutputToken(finalTokenInPath); // Transfer the input tokens from the actor to this contract address tokenIn = address(bytes20(path)); IERC20(tokenIn).transferFrom(processActionParams.actorProfileOwner, address(this), amountIn); // Calculate and collect the protocol fee uint256 protocolFee = getSplitsTokenIn(amountIn); feesCollected[tokenIn] += protocolFee; amountIn -= protocolFee; // Approve the Uniswap router to spend the tokens checkAllowance(tokenIn, amountIn); // Set up the parameters for the multi-hop swap ISwapRouter.ExactInputParams memory params = ISwapRouter.ExactInputParams({ path: path, recipient: address(this), deadline: deadline, amountIn: amountIn, amountOutMinimum: amountOutMinimum }); // Execute the multi-hop swap uint256 amountOut = uniswapV3Router.exactInput(params); // get reward payouts bool isDirectPromotion = post.token != address(0); bool isReferral = processActionParams.referrerProfileIds.length > 0; bool hasClient = clientAddress != address(0); (uint256 poster, uint256 swapper, uint256 referrer, uint256 client, uint256 lens) = getSplitsTokenOut( amountOut, isDirectPromotion, rewardsPool.percentReward, rewardsPool.cap, rewardsPool.rewardsAmount, post.sharedRewardPercent, isReferral, hasClient ); IERC20 _token; if (isDirectPromotion) { _token = IERC20(finalTokenInPath); } else { _token = IERC20(rewardsPool.token); } _token.transfer(post.recipient, poster); if (swapper > 0) { _token.transfer(processActionParams.actorProfileOwner, swapper); } if (isReferral) { _token.transfer(hub.ownerOf(processActionParams.referrerProfileIds[0]), referrer); } if (hasClient) { _token.transfer(clientAddress, client); } if (lens > 0) { _token.transfer(hub.getTreasury(), lens); } emit RewardsPaid(post.rewardsPoolId, amountOut, swapper, poster, referrer, client); if (rewardsPool.collectionId != 0) { // award 100 madfi points for the swapper madSBT.handleRewardsUpdate(processActionParams.actorProfileOwner, rewardsPool.collectionId, 3); // award 20 madfi points for the poster madSBT.handleRewardsUpdate(post.recipient, rewardsPool.collectionId, 5); } return abi.encode(amountOut); } /// @notice Extracts the final token address from a multi-hop swap path. function extractFinalTokenAddress(bytes memory path) public pure returns (address finalToken) { require(path.length >= 20, "Path too short"); bytes memory last20Bytes = slice(path, path.length - 20, 20); finalToken = toAddress(last20Bytes); } function slice(bytes memory data, uint256 start, uint256 length) internal pure returns (bytes memory) { bytes memory result = new bytes(length); for (uint256 i = 0; i < length; i++) { result[i] = data[i + start]; } return result; } function toAddress(bytes memory data) internal pure returns (address addr) { require(data.length == 20, "Invalid data length"); assembly { addr := mload(add(data, 20)) } } /** * @notice Returns the token amounts that go to each party * @param amountOut The amount received from the swap * @param isDirectPromotion Whether this is a direct promotion or not * @param percentReward The percent of amountOut being distributed as reward from reward pool * @param cap The max amount of rewards to distribute per tx from reward pool * @param remainingRewards The remaining rewards in the reward pool * @param sharedRewardPercent The percent of their reward the poster shares with swapper * @param isReferral Whether this post was a referral or not * @param hasClient Whether this post has a client address defined or not * * @return poster The amount going to the poster * @return swapper The amount going to the swapper * @return referrer The amount going to the referrer * @return client The amount going to the client */ function getSplitsTokenOut( uint256 amountOut, bool isDirectPromotion, uint256 percentReward, uint256 cap, uint256 remainingRewards, uint256 sharedRewardPercent, bool isReferral, bool hasClient ) public view returns (uint256 poster, uint256 swapper, uint256 referrer, uint256 client, uint256 lens) { uint256 treasuryFee = hub.getTreasuryFee(); if (isDirectPromotion) { uint256 totalRewards = amountOut * DIRECT_PROMOTION_SPLIT / 100_00; swapper = amountOut - totalRewards; client = hasClient ? totalRewards * CLIENT_PERCENT / 100_00 : 0; lens = totalRewards * treasuryFee / 100_00; totalRewards -= client + lens; if (isReferral) { referrer = totalRewards / 2; poster = totalRewards / 2; } else { referrer = 0; poster = totalRewards; } } else { uint256 totalRewards = amountOut * percentReward / 100_00; if (totalRewards > cap) { totalRewards = cap; } if (totalRewards > remainingRewards) { totalRewards = remainingRewards; } client = hasClient ? totalRewards * CLIENT_PERCENT / 100_00 : 0; lens = totalRewards * treasuryFee / 100_00; swapper = (totalRewards - client - lens) * sharedRewardPercent / 100_00; uint256 remaining = totalRewards - client - swapper - lens; if (isReferral) { referrer = remaining / 2; poster = remaining / 2; } else { referrer = 0; poster = remaining; } swapper += amountOut; } } /** * @notice Returns the splits of incoming tokens * @param amountIn The amount of the incoming token * @return protocol The amount going to the protocol */ function getSplitsTokenIn(uint256 amountIn) public view returns (uint256 protocol) { return PROTOCOL_FEE * amountIn / 100_00; } /** * @notice Checks if the router already has enough allowance and approves max allowance if it's not already set. * @param tokenIn The token to check allowance for. * @param amountIn The amount of tokens to check allowance for. */ function checkAllowance(address tokenIn, uint256 amountIn) private { // Check if the router already has enough allowance uint256 currentAllowance = IERC20(tokenIn).allowance(address(this), address(uniswapV3Router)); uint256 maxAllowance = type(uint256).max; if (currentAllowance < amountIn) { // Approve max allowance if it's not already set to save on future transactions IERC20(tokenIn).approve(address(uniswapV3Router), maxAllowance); } } /** * @notice Withdraws fees collected in the given token. * @param token The token to withdraw fees for. */ function withdrawProtocolFees(address token) external onlyOwner { address _to = owner(); if (token == address(0)) { payable(_to).transfer(address(this).balance); } else { uint256 _fees = feesCollected[token]; feesCollected[token] = 0; IERC20(token).transfer(_to, _fees); } emit FeesWithdrawn(token, _to); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol) pragma solidity ^0.8.0; import "../utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @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 amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` 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 amount) 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 `amount` 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 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` 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 amount ) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol) pragma solidity ^0.8.0; import "../IERC721.sol"; /** * @title ERC-721 Non-Fungible Token Standard, optional metadata extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Metadata is IERC721 { /** * @dev Returns the token collection name. */ function name() external view returns (string memory); /** * @dev Returns the token collection symbol. */ function symbol() external view returns (string memory); /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) external view returns (string memory); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol) pragma solidity ^0.8.0; import "../../utils/introspection/IERC165.sol"; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721 is IERC165 { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes calldata data ) external; /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721 * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must * understand this adds an external call which potentially creates a reentrancy vulnerability. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool _approved) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.15; import {Errors} from 'lens/libraries/constants/Errors.sol'; /** * @title HubRestricted * @author Lens Protocol * * @notice This abstract contract adds a public `HUB` immutable field, as well as an `onlyHub` modifier, * to inherit from contracts that have functions restricted to be only called by the Lens hub. */ abstract contract HubRestricted { address public immutable HUB; modifier onlyHub() { if (msg.sender != HUB) { revert Errors.NotHub(); } _; } constructor(address hub) { HUB = hub; } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0; /** * @title IERC721Burnable * @author Lens Protocol * * @notice Extension of ERC-721 including a function that allows the token to be burned. */ interface IERC721Burnable { /** * @notice Burns an NFT, removing it from circulation and essentially destroying it. * @custom:permission Owner of the NFT. * * @param tokenId The token ID of the token to burn. */ function burn(uint256 tokenId) external; }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0; /** * @title IERC721MetaTx * @author Lens Protocol * * @notice Extension of ERC-721 including meta-tx signatures related functions. */ interface IERC721MetaTx { /** * @notice Returns the current signature nonce of the given signer. * * @param signer The address for which to query the nonce. * * @return uint256 The current nonce of the given signer. */ function nonces(address signer) external view returns (uint256); /** * @notice Returns the EIP-712 domain separator for this contract. * * @return bytes32 The domain separator. */ function getDomainSeparator() external view returns (bytes32); }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0; import {Types} from 'lens/libraries/constants/Types.sol'; /** * @title IERC721Timestamped * @author Lens Protocol * * @notice Extension of ERC-721 including a struct for token data, which contains the owner and the mint timestamp, as * well as their associated getters. */ interface IERC721Timestamped { /** * @notice Returns the mint timestamp associated with a given NFT. * * @param tokenId The token ID of the NFT to query the mint timestamp for. * * @return uint256 Mint timestamp, this is stored as a uint96 but returned as a uint256 to reduce unnecessary * padding. */ function mintTimestampOf(uint256 tokenId) external view returns (uint256); /** * @notice Returns the token data associated with a given NFT. This allows fetching the token owner and * mint timestamp in a single call. * * @param tokenId The token ID of the NFT to query the token data for. * * @return TokenData A struct containing both the owner address and the mint timestamp. */ function tokenDataOf(uint256 tokenId) external view returns (Types.TokenData memory); /** * @notice Returns whether a token with the given token ID exists. * * @param tokenId The token ID of the NFT to check existence for. * * @return bool True if the token exists. */ function exists(uint256 tokenId) external view returns (bool); /** * @notice Returns the amount of tokens in circulation. * * @return uint256 The current total supply of tokens. */ function totalSupply() external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0; import {IERC721} from '@openzeppelin/contracts/token/ERC721/IERC721.sol'; import {IERC721Timestamped} from 'lens/interfaces/IERC721Timestamped.sol'; import {IERC721Burnable} from 'lens/interfaces/IERC721Burnable.sol'; import {IERC721MetaTx} from 'lens/interfaces/IERC721MetaTx.sol'; import {IERC721Metadata} from '@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol'; interface ILensERC721 is IERC721, IERC721Timestamped, IERC721Burnable, IERC721MetaTx, IERC721Metadata {}
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0; import {Types} from 'lens/libraries/constants/Types.sol'; /** * @title ILensGovernable * @author Lens Protocol * * @notice This is the interface for the Lens Protocol main governance functions. */ interface ILensGovernable { /** * @notice Sets the privileged governance role. * @custom:permissions Governance. * * @param newGovernance The new governance address to set. */ function setGovernance(address newGovernance) external; /** * @notice Sets the emergency admin, which is a permissioned role able to set the protocol state. * @custom:permissions Governance. * * @param newEmergencyAdmin The new emergency admin address to set. */ function setEmergencyAdmin(address newEmergencyAdmin) external; /** * @notice Sets the protocol state to either a global pause, a publishing pause or an unpaused state. * @custom:permissions Governance or Emergency Admin. Emergency Admin can only restrict more. * * @param newState The state to set. It can be one of the following: * - Unpaused: The protocol is fully operational. * - PublishingPaused: The protocol is paused for publishing, but it is still operational for others operations. * - Paused: The protocol is paused for all operations. */ function setState(Types.ProtocolState newState) external; /** * @notice Adds or removes a profile creator from the whitelist. * @custom:permissions Governance. * * @param profileCreator The profile creator address to add or remove from the whitelist. * @param whitelist Whether or not the profile creator should be whitelisted. */ function whitelistProfileCreator(address profileCreator, bool whitelist) external; /** * @notice Sets the profile token URI contract. * @custom:permissions Governance. * * @param profileTokenURIContract The profile token URI contract to set. */ function setProfileTokenURIContract(address profileTokenURIContract) external; /** * @notice Sets the follow token URI contract. * @custom:permissions Governance. * * @param followTokenURIContract The follow token URI contract to set. */ function setFollowTokenURIContract(address followTokenURIContract) external; /** * @notice Sets the treasury address. * @custom:permissions Governance * * @param newTreasury The new treasury address to set. */ function setTreasury(address newTreasury) external; /** * @notice Sets the treasury fee. * @custom:permissions Governance * * @param newTreasuryFee The new treasury fee to set. */ function setTreasuryFee(uint16 newTreasuryFee) external; /** * @notice Returns the currently configured governance address. * * @return address The address of the currently configured governance. */ function getGovernance() external view returns (address); /** * @notice Gets the state currently set in the protocol. It could be a global pause, a publishing pause or an * unpaused state. * @custom:permissions Anyone. * * @return Types.ProtocolState The state currently set in the protocol. */ function getState() external view returns (Types.ProtocolState); /** * @notice Returns whether or not a profile creator is whitelisted. * * @param profileCreator The address of the profile creator to check. * * @return bool True if the profile creator is whitelisted, false otherwise. */ function isProfileCreatorWhitelisted(address profileCreator) external view returns (bool); /** * @notice Returns the treasury address. * * @return address The treasury address. */ function getTreasury() external view returns (address); /** * @notice Returns the treasury fee. * * @return uint16 The treasury fee. */ function getTreasuryFee() external view returns (uint16); /** * @notice Returns the treasury address and treasury fee in a single call. * * @return tuple First, the treasury address, second, the treasury fee. */ function getTreasuryData() external view returns (address, uint16); /** * @notice Gets the profile token URI contract. * * @return address The profile token URI contract. */ function getProfileTokenURIContract() external view returns (address); /** * @notice Gets the follow token URI contract. * * @return address The follow token URI contract. */ function getFollowTokenURIContract() external view returns (address); }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0; import {ILensProtocol} from 'lens/interfaces/ILensProtocol.sol'; import {ILensGovernable} from 'lens/interfaces/ILensGovernable.sol'; import {ILensHubEventHooks} from 'lens/interfaces/ILensHubEventHooks.sol'; import {ILensImplGetters} from 'lens/interfaces/ILensImplGetters.sol'; import {ILensProfiles} from 'lens/interfaces/ILensProfiles.sol'; import {ILensVersion} from 'lens/interfaces/ILensVersion.sol'; interface ILensHub is ILensProfiles, ILensProtocol, ILensGovernable, ILensHubEventHooks, ILensImplGetters, ILensVersion {}
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0; /** * @title ILensHubEventHooks * @author Lens Protocol * * @notice This is the interface for the LensHub contract's event hooks. As we want most of the core events to be * emitted by the LensHub contract, event hooks are needed for core events generated by pheripheral contracts. */ interface ILensHubEventHooks { /** * @dev Helper function to emit an `Unfollowed` event from the hub, to be consumed by indexers to track unfollows. * @custom:permissions FollowNFT of the Profile unfollowed. * * @param unfollowerProfileId The ID of the profile that executed the unfollow. * @param idOfProfileUnfollowed The ID of the profile that was unfollowed. * @param transactionExecutor The address of the account executing the unfollow operation. */ function emitUnfollowedEvent( uint256 unfollowerProfileId, uint256 idOfProfileUnfollowed, address transactionExecutor ) external; }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0; /** * @title ILensImplGetters * @author Lens Protocol * * @notice This is the interface for the LensHub contract's implementation getters. These implementations will be used * for deploying each respective contract for each profile. */ interface ILensImplGetters { /** * @notice Returns the Follow NFT implementation address that is used for all deployed Follow NFTs. * * @return address The Follow NFT implementation address. */ function getFollowNFTImpl() external view returns (address); /** * @notice Returns the Collect NFT implementation address that is used for each new deployed Collect NFT. * @custom:pending-deprecation * * @return address The Collect NFT implementation address. */ function getLegacyCollectNFTImpl() external view returns (address); /** * @notice Returns the address of the registry that stores all modules that are used by the Lens Protocol. * * @return address The address of the Module Registry contract. */ function getModuleRegistry() external view returns (address); }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0; import {ILensERC721} from 'lens/interfaces/ILensERC721.sol'; interface ILensProfiles is ILensERC721 { /** * @notice DANGER: Triggers disabling the profile protection mechanism for the msg.sender, which will allow * transfers or approvals over profiles held by it. * Disabling the mechanism will have a timelock before it becomes effective, allowing the owner to re-enable * the protection back in case of being under attack. * The protection layer only applies to EOA wallets. */ function DANGER__disableTokenGuardian() external; /** * @notice Enables back the profile protection mechanism for the msg.sender, preventing profile transfers or * approvals (except when revoking them). * The protection layer only applies to EOA wallets. */ function enableTokenGuardian() external; /** * @notice Returns the timestamp at which the Token Guardian will become effectively disabled. * * @param wallet The address to check the timestamp for. * * @return uint256 The timestamp at which the Token Guardian will become effectively disabled. Zero if enabled. */ function getTokenGuardianDisablingTimestamp(address wallet) external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0; import {Types} from 'lens/libraries/constants/Types.sol'; /** * @title ILensProtocol * @author Lens Protocol * * @notice This is the interface for Lens Protocol's core functions. It contains all the entry points for performing * social operations. */ interface ILensProtocol { /** * @notice Creates a profile with the specified parameters, minting a Profile NFT to the given recipient. * @custom:permissions Any whitelisted profile creator. * * @param createProfileParams A CreateProfileParams struct containing the needed params. */ function createProfile(Types.CreateProfileParams calldata createProfileParams) external returns (uint256); /** * @notice Sets the metadata URI for the given profile. * @custom:permissions Profile Owner or Delegated Executor. * * @param profileId The token ID of the profile to set the metadata URI for. * @param metadataURI The metadata URI to set for the given profile. */ function setProfileMetadataURI(uint256 profileId, string calldata metadataURI) external; /** * @custom:meta-tx setProfileMetadataURI. */ function setProfileMetadataURIWithSig( uint256 profileId, string calldata metadataURI, Types.EIP712Signature calldata signature ) external; /** * @notice Sets the follow module for the given profile. * @custom:permissions Profile Owner or Delegated Executor. * * @param profileId The token ID of the profile to set the follow module for. * @param followModule The follow module to set for the given profile, must be whitelisted. * @param followModuleInitData The data to be passed to the follow module for initialization. */ function setFollowModule(uint256 profileId, address followModule, bytes calldata followModuleInitData) external; /** * @custom:meta-tx setFollowModule. */ function setFollowModuleWithSig( uint256 profileId, address followModule, bytes calldata followModuleInitData, Types.EIP712Signature calldata signature ) external; /** * @notice Changes the delegated executors configuration for the given profile. It allows setting the approvals for * delegated executors in the specified configuration, as well as switching to it. * @custom:permissions Profile Owner. * * @param delegatorProfileId The ID of the profile to which the delegated executor is being changed for. * @param delegatedExecutors The array of delegated executors to set the approval for. * @param approvals The array of booleans indicating the corresponding executor's new approval status. * @param configNumber The number of the configuration where the executor approval state is being set. * @param switchToGivenConfig A boolean indicating if the configuration must be switched to the one with the given * number. */ function changeDelegatedExecutorsConfig( uint256 delegatorProfileId, address[] calldata delegatedExecutors, bool[] calldata approvals, uint64 configNumber, bool switchToGivenConfig ) external; /** * @notice Changes the delegated executors configuration for the given profile under the current configuration. * @custom:permissions Profile Owner. * * @param delegatorProfileId The ID of the profile to which the delegated executor is being changed for. * @param delegatedExecutors The array of delegated executors to set the approval for. * @param approvals The array of booleans indicating the corresponding executor's new approval status. */ function changeDelegatedExecutorsConfig( uint256 delegatorProfileId, address[] calldata delegatedExecutors, bool[] calldata approvals ) external; /** * @custom:meta-tx changeDelegatedExecutorsConfig. */ function changeDelegatedExecutorsConfigWithSig( uint256 delegatorProfileId, address[] calldata delegatedExecutors, bool[] calldata approvals, uint64 configNumber, bool switchToGivenConfig, Types.EIP712Signature calldata signature ) external; /** * @notice Publishes a post. * Post is the most basic publication type, and can be used to publish any kind of content. * Posts can have these types of modules initialized: * - Action modules: any number of publication actions (e.g. collect, tip, etc.) * - Reference module: a module handling the rules when referencing this post (e.g. token-gated comments) * @custom:permissions Profile Owner or Delegated Executor. * * @param postParams A PostParams struct containing the needed parameters. * * @return uint256 An integer representing the post's publication ID. */ function post(Types.PostParams calldata postParams) external returns (uint256); /** * @custom:meta-tx post. */ function postWithSig( Types.PostParams calldata postParams, Types.EIP712Signature calldata signature ) external returns (uint256); /** * @notice Publishes a comment on the given publication. * Comment is a type of reference publication that points to another publication. * Comments can have these types of modules initialized: * - Action modules: any number of publication actions (e.g. collect, tip, etc.) * - Reference module: a module handling the rules when referencing this comment (e.g. token-gated mirrors) * Comments can have referrers (e.g. publications or profiles that helped to discover the pointed publication). * @custom:permissions Profile Owner or Delegated Executor. * * @param commentParams A CommentParams struct containing the needed parameters. * * @return uint256 An integer representing the comment's publication ID. */ function comment(Types.CommentParams calldata commentParams) external returns (uint256); /** * @custom:meta-tx comment. */ function commentWithSig( Types.CommentParams calldata commentParams, Types.EIP712Signature calldata signature ) external returns (uint256); /** * @notice Publishes a mirror of the given publication. * Mirror is a type of reference publication that points to another publication but doesn't have content. * Mirrors don't have any modules initialized. * Mirrors can have referrers (e.g. publications or profiles that allowed to discover the pointed publication). * You cannot mirror a mirror, comment on a mirror, or quote a mirror. * @custom:permissions Profile Owner or Delegated Executor. * * @param mirrorParams A MirrorParams struct containing the necessary parameters. * * @return uint256 An integer representing the mirror's publication ID. */ function mirror(Types.MirrorParams calldata mirrorParams) external returns (uint256); /** * @custom:meta-tx mirror. */ function mirrorWithSig( Types.MirrorParams calldata mirrorParams, Types.EIP712Signature calldata signature ) external returns (uint256); /** * @notice Publishes a quote of the given publication. * Quote is a type of reference publication similar to mirror, but it has content and modules. * Quotes can have these types of modules initialized: * - Action modules: any number of publication actions (e.g. collect, tip, etc.) * - Reference module: a module handling the rules when referencing this quote (e.g. token-gated comments on quote) * Quotes can have referrers (e.g. publications or profiles that allowed to discover the pointed publication). * Unlike mirrors, you can mirror a quote, comment on a quote, or quote a quote. * @custom:permissions Profile Owner or Delegated Executor. * * @param quoteParams A QuoteParams struct containing the needed parameters. * * @return uint256 An integer representing the quote's publication ID. */ function quote(Types.QuoteParams calldata quoteParams) external returns (uint256); /** * @custom:meta-tx quote. */ function quoteWithSig( Types.QuoteParams calldata quoteParams, Types.EIP712Signature calldata signature ) external returns (uint256); /** * @notice Follows given profiles, executing each profile's follow module logic (if any). * @custom:permissions Profile Owner or Delegated Executor. * * @dev Both the `idsOfProfilesToFollow`, `followTokenIds`, and `datas` arrays must be of the same length, * regardless if the profiles do not have a follow module set. * * @param followerProfileId The ID of the profile the follows are being executed for. * @param idsOfProfilesToFollow The array of IDs of profiles to follow. * @param followTokenIds The array of follow token IDs to use for each follow (0 if you don't own a follow token). * @param datas The arbitrary data array to pass to the follow module for each profile if needed. * * @return uint256[] An array of follow token IDs representing the follow tokens created for each follow. */ function follow( uint256 followerProfileId, uint256[] calldata idsOfProfilesToFollow, uint256[] calldata followTokenIds, bytes[] calldata datas ) external returns (uint256[] memory); /** * @custom:meta-tx follow. */ function followWithSig( uint256 followerProfileId, uint256[] calldata idsOfProfilesToFollow, uint256[] calldata followTokenIds, bytes[] calldata datas, Types.EIP712Signature calldata signature ) external returns (uint256[] memory); /** * @notice Unfollows given profiles. * @custom:permissions Profile Owner or Delegated Executor. * * @param unfollowerProfileId The ID of the profile the unfollows are being executed for. * @param idsOfProfilesToUnfollow The array of IDs of profiles to unfollow. */ function unfollow(uint256 unfollowerProfileId, uint256[] calldata idsOfProfilesToUnfollow) external; /** * @custom:meta-tx unfollow. */ function unfollowWithSig( uint256 unfollowerProfileId, uint256[] calldata idsOfProfilesToUnfollow, Types.EIP712Signature calldata signature ) external; /** * @notice Sets the block status for the given profiles. Changing a profile's block status to `true` (i.e. blocked), * when will also force them to unfollow. * Blocked profiles cannot perform any actions with the profile that blocked them: they cannot comment or mirror * their publications, they cannot follow them, they cannot collect, tip them, etc. * @custom:permissions Profile Owner or Delegated Executor. * * @dev Both the `idsOfProfilesToSetBlockStatus` and `blockStatus` arrays must be of the same length. * * @param byProfileId The ID of the profile that is blocking/unblocking somebody. * @param idsOfProfilesToSetBlockStatus The array of IDs of profiles to set block status. * @param blockStatus The array of block statuses to use for each (true is blocked). */ function setBlockStatus( uint256 byProfileId, uint256[] calldata idsOfProfilesToSetBlockStatus, bool[] calldata blockStatus ) external; /** * @custom:meta-tx setBlockStatus. */ function setBlockStatusWithSig( uint256 byProfileId, uint256[] calldata idsOfProfilesToSetBlockStatus, bool[] calldata blockStatus, Types.EIP712Signature calldata signature ) external; /** * @notice Collects a given publication via signature with the specified parameters. * Collect can have referrers (e.g. publications or profiles that allowed to discover the pointed publication). * @custom:permissions Collector Profile Owner or its Delegated Executor. * @custom:pending-deprecation Collect modules were replaced by PublicationAction Collect modules in V2. This method * is left here for backwards compatibility with posts made in V1 that had Collect modules. * * @param collectParams A CollectParams struct containing the parameters. * * @return uint256 An integer representing the minted token ID. */ function collectLegacy(Types.LegacyCollectParams calldata collectParams) external returns (uint256); /** * @custom:meta-tx collect. * @custom:pending-deprecation */ function collectLegacyWithSig( Types.LegacyCollectParams calldata collectParams, Types.EIP712Signature calldata signature ) external returns (uint256); /** * @notice Acts on a given publication with the specified parameters. * You can act on a publication except a mirror (if it has at least one action module initialized). * Actions can have referrers (e.g. publications or profiles that allowed to discover the pointed publication). * @custom:permissions Actor Profile Owner or its Delegated Executor. * * @param publicationActionParams A PublicationActionParams struct containing the parameters. * * @return bytes Arbitrary data the action module returns. */ function act(Types.PublicationActionParams calldata publicationActionParams) external returns (bytes memory); /** * @custom:meta-tx act. */ function actWithSig( Types.PublicationActionParams calldata publicationActionParams, Types.EIP712Signature calldata signature ) external returns (bytes memory); /** * @dev This function is used to invalidate signatures by incrementing the nonce of the signer. * @param increment The amount to increment the nonce by (max 255). */ function incrementNonce(uint8 increment) external; ///////////////////////////////// /// VIEW FUNCTIONS /// ///////////////////////////////// /** * @notice Returns whether or not `followerProfileId` is following `followedProfileId`. * * @param followerProfileId The ID of the profile whose following state should be queried. * @param followedProfileId The ID of the profile whose followed state should be queried. * * @return bool True if `followerProfileId` is following `followedProfileId`, false otherwise. */ function isFollowing(uint256 followerProfileId, uint256 followedProfileId) external view returns (bool); /** * @notice Returns whether the given address is approved as delegated executor, in the configuration with the given * number, to act on behalf of the given profile. * * @param delegatorProfileId The ID of the profile to check the delegated executor approval for. * @param delegatedExecutor The address to query the delegated executor approval for. * @param configNumber The number of the configuration where the executor approval state is being queried. * * @return bool True if the address is approved as a delegated executor to act on behalf of the profile in the * given configuration, false otherwise. */ function isDelegatedExecutorApproved( uint256 delegatorProfileId, address delegatedExecutor, uint64 configNumber ) external view returns (bool); /** * @notice Returns whether the given address is approved as delegated executor, in the current configuration, to act * on behalf of the given profile. * * @param delegatorProfileId The ID of the profile to check the delegated executor approval for. * @param delegatedExecutor The address to query the delegated executor approval for. * * @return bool True if the address is approved as a delegated executor to act on behalf of the profile in the * current configuration, false otherwise. */ function isDelegatedExecutorApproved( uint256 delegatorProfileId, address delegatedExecutor ) external view returns (bool); /** * @notice Returns the current delegated executor config number for the given profile. * * @param delegatorProfileId The ID of the profile from which the delegated executors config number is being queried * * @return uint256 The current delegated executor configuration number. */ function getDelegatedExecutorsConfigNumber(uint256 delegatorProfileId) external view returns (uint64); /** * @notice Returns the previous used delegated executor config number for the given profile. * * @param delegatorProfileId The ID of the profile from which the delegated executors' previous configuration number * set is being queried. * * @return uint256 The delegated executor configuration number previously set. It will coincide with the current * configuration set if it was never switched from the default one. */ function getDelegatedExecutorsPrevConfigNumber(uint256 delegatorProfileId) external view returns (uint64); /** * @notice Returns the maximum delegated executor config number for the given profile. * This is the maximum config number that was ever used by this profile. * When creating a new clean configuration, you can only use a number that is maxConfigNumber + 1. * * @param delegatorProfileId The ID of the profile from which the delegated executors' maximum configuration number * set is being queried. * * @return uint256 The delegated executor maximum configuration number set. */ function getDelegatedExecutorsMaxConfigNumberSet(uint256 delegatorProfileId) external view returns (uint64); /** * @notice Returns whether `profileId` is blocked by `byProfileId`. * See setBlockStatus() for more information on how blocking works on the platform. * * @param profileId The ID of the profile whose blocked status should be queried. * @param byProfileId The ID of the profile whose blocker status should be queried. * * @return bool True if `profileId` is blocked by `byProfileId`, false otherwise. */ function isBlocked(uint256 profileId, uint256 byProfileId) external view returns (bool); /** * @notice Returns the URI associated with a given publication. * This is used to store the publication's metadata, e.g.: content, images, etc. * * @param profileId The token ID of the profile that published the publication to query. * @param pubId The publication ID of the publication to query. * * @return string The URI associated with a given publication. */ function getContentURI(uint256 profileId, uint256 pubId) external view returns (string memory); /** * @notice Returns the full profile struct associated with a given profile token ID. * * @param profileId The token ID of the profile to query. * * @return Profile The profile struct of the given profile. */ function getProfile(uint256 profileId) external view returns (Types.Profile memory); /** * @notice Returns the full publication struct for a given publication. * * @param profileId The token ID of the profile that published the publication to query. * @param pubId The publication ID of the publication to query. * * @return Publication The publication struct associated with the queried publication. */ function getPublication(uint256 profileId, uint256 pubId) external view returns (Types.PublicationMemory memory); /** * @notice Returns the type of a given publication. * The type can be one of the following (see PublicationType enum): * - Nonexistent * - Post * - Comment * - Mirror * - Quote * * @param profileId The token ID of the profile that published the publication to query. * @param pubId The publication ID of the publication to query. * * @return PublicationType The publication type of the queried publication. */ function getPublicationType(uint256 profileId, uint256 pubId) external view returns (Types.PublicationType); /** * @notice Returns wether a given Action Module is enabled for a given publication. * * @param profileId The token ID of the profile that published the publication to query. * @param pubId The publication ID of the publication to query. * @param module The address of the Action Module to query. * * @return bool True if the Action Module is enabled for the queried publication, false if not. */ function isActionModuleEnabledInPublication( uint256 profileId, uint256 pubId, address module ) external view returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0; /** * @title ILensVersion * @author Lens Protocol * * @notice This is the interface for the LensHub Version getters and emitter. * It allows to emit a LensHub version during an upgrade, and also to get the current version. */ interface ILensVersion { /** * @notice Returns the LensHub current Version. * * @return version The LensHub current Version. */ function getVersion() external view returns (string memory); /** * @notice Returns the LensHub current Git Commit. * * @return gitCommit The LensHub current Git Commit. */ function getGitCommit() external view returns (bytes20); /** * @notice Emits the LensHub current Version. Used in upgradeAndCall(). */ function emitVersion() external; }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0; import {Types} from 'lens/libraries/constants/Types.sol'; /** * @title IPublicationAction * @author Lens Protocol * * @notice This is the standard interface for all Lens-compatible Publication Actions. * Publication action modules allow users to execute actions directly from a publication, like: * - Minting NFTs. * - Collecting a publication. * - Sending funds to the publication author (e.g. tipping). * - Etc. * Referrers are supported, so any publication or profile that references the publication can receive a share from the * publication's action if the action module supports it. */ interface IPublicationActionModule { /** * @notice Initializes the action module for the given publication being published with this Action module. * @custom:permissions LensHub. * * @param profileId The profile ID of the author publishing the content with this Publication Action. * @param pubId The publication ID being published. * @param transactionExecutor The address of the transaction executor (e.g. for any funds to transferFrom). * @param data Arbitrary data passed from the user to be decoded by the Action Module during initialization. * * @return bytes Any custom ABI-encoded data. This will be a LensHub event params that can be used by * indexers or UIs. */ function initializePublicationAction( uint256 profileId, uint256 pubId, address transactionExecutor, bytes calldata data ) external returns (bytes memory); /** * @notice Processes the action for a given publication. This includes the action's logic and any monetary/token * operations. * @custom:permissions LensHub. * * @param processActionParams The parameters needed to execute the publication action. * * @return bytes Any custom ABI-encoded data. This will be a LensHub event params that can be used by * indexers or UIs. */ function processPublicationAction(Types.ProcessActionParams calldata processActionParams) external returns (bytes memory); }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0; library Errors { error CannotInitImplementation(); error Initialized(); error SignatureExpired(); error SignatureInvalid(); error InvalidOwner(); error NotOwnerOrApproved(); error NotHub(); error TokenDoesNotExist(); error NotGovernance(); error NotGovernanceOrEmergencyAdmin(); error EmergencyAdminCanOnlyPauseFurther(); error NotProfileOwner(); error PublicationDoesNotExist(); error CallerNotFollowNFT(); error CallerNotCollectNFT(); // Legacy error ArrayMismatch(); error NotWhitelisted(); error NotRegistered(); error InvalidParameter(); error ExecutorInvalid(); error Blocked(); error SelfBlock(); error NotFollowing(); error SelfFollow(); error InvalidReferrer(); error InvalidPointedPub(); error NonERC721ReceiverImplementer(); error AlreadyEnabled(); // Module Errors error InitParamsInvalid(); error ActionNotAllowed(); error CollectNotAllowed(); // Used in LegacyCollectLib (pending deprecation) // MultiState Errors error Paused(); error PublishingPaused(); // Profile Guardian Errors error GuardianEnabled(); error NotEOA(); error DisablingAlreadyTriggered(); // Migration Errors error NotMigrationAdmin(); }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0; /** * @title Types * @author Lens Protocol * * @notice A standard library of data types used throughout the Lens Protocol. */ library Types { /** * @notice ERC721Timestamped storage. Contains the owner address and the mint timestamp for every NFT. * * Note: Instead of the owner address in the _tokenOwners private mapping, we now store it in the * _tokenData mapping, alongside the mint timestamp. * * @param owner The token owner. * @param mintTimestamp The mint timestamp. */ struct TokenData { address owner; uint96 mintTimestamp; } /** * @notice A struct containing token follow-related data. * * @param followerProfileId The ID of the profile using the token to follow. * @param originalFollowTimestamp The timestamp of the first follow performed with the token. * @param followTimestamp The timestamp of the current follow, if a profile is using the token to follow. * @param profileIdAllowedToRecover The ID of the profile allowed to recover the follow ID, if any. */ struct FollowData { uint160 followerProfileId; uint48 originalFollowTimestamp; uint48 followTimestamp; uint256 profileIdAllowedToRecover; } /** * @notice An enum containing the different states the protocol can be in, limiting certain actions. * * @param Unpaused The fully unpaused state. * @param PublishingPaused The state where only publication creation functions are paused. * @param Paused The fully paused state. */ enum ProtocolState { Unpaused, PublishingPaused, Paused } /** * @notice An enum specifically used in a helper function to easily retrieve the publication type for integrations. * * @param Nonexistent An indicator showing the queried publication does not exist. * @param Post A standard post, having an URI, action modules and no pointer to another publication. * @param Comment A comment, having an URI, action modules and a pointer to another publication. * @param Mirror A mirror, having a pointer to another publication, but no URI or action modules. * @param Quote A quote, having an URI, action modules, and a pointer to another publication. */ enum PublicationType { Nonexistent, Post, Comment, Mirror, Quote } /** * @notice A struct containing the necessary information to reconstruct an EIP-712 typed data signature. * * @param signer The address of the signer. Specially needed as a parameter to support EIP-1271. * @param v The signature's recovery parameter. * @param r The signature's r parameter. * @param s The signature's s parameter. * @param deadline The signature's deadline. */ struct EIP712Signature { address signer; uint8 v; bytes32 r; bytes32 s; uint256 deadline; } /** * @notice A struct containing profile data. * * @param pubCount The number of publications made to this profile. * @param followModule The address of the current follow module in use by this profile, can be address(0) in none. * @param followNFT The address of the followNFT associated with this profile. It can be address(0) if the * profile has not been followed yet, as the collection is lazy-deployed upon the first follow. * @param __DEPRECATED__handle DEPRECATED in V2: handle slot, was replaced with LensHandles. * @param __DEPRECATED__imageURI DEPRECATED in V2: The URI to be used for the profile image. * @param __DEPRECATED__followNFTURI DEPRECATED in V2: The URI used for the follow NFT image. * @param metadataURI MetadataURI is used to store the profile's metadata, for example: displayed name, description, * interests, etc. */ struct Profile { uint256 pubCount; // offset 0 address followModule; // offset 1 address followNFT; // offset 2 string __DEPRECATED__handle; // offset 3 string __DEPRECATED__imageURI; // offset 4 string __DEPRECATED__followNFTURI; // Deprecated in V2 as we have a common tokenURI for all Follows, offset 5 string metadataURI; // offset 6 } /** * @notice A struct containing publication data. * * @param pointedProfileId The profile token ID to point the publication to. * @param pointedPubId The publication ID to point the publication to. * These are used to implement the "reference" feature of the platform and is used in: * - Mirrors * - Comments * - Quotes * There are (0,0) if the publication is not pointing to any other publication (i.e. the publication is a Post). * @param contentURI The URI to set for the content of publication (can be ipfs, arweave, http, etc). * @param referenceModule Reference module associated with this profile, if any. * @param __DEPRECATED__collectModule Collect module associated with this publication, if any. Deprecated in V2. * @param __DEPRECATED__collectNFT Collect NFT associated with this publication, if any. Deprecated in V2. * @param pubType The type of publication, can be Nonexistent, Post, Comment, Mirror or Quote. * @param rootProfileId The profile ID of the root post (to determine if comments/quotes and mirrors come from it). * Posts, V1 publications and publications rooted in V1 publications don't have it set. * @param rootPubId The publication ID of the root post (to determine if comments/quotes and mirrors come from it). * Posts, V1 publications and publications rooted in V1 publications don't have it set. * @param actionModuleEnabled The action modules enabled in a given publication. */ struct Publication { uint256 pointedProfileId; uint256 pointedPubId; string contentURI; address referenceModule; address __DEPRECATED__collectModule; // Deprecated in V2 address __DEPRECATED__collectNFT; // Deprecated in V2 // Added in Lens V2, so these will be zero for old publications: PublicationType pubType; uint256 rootProfileId; uint256 rootPubId; mapping(address => bool) actionModuleEnabled; } struct PublicationMemory { uint256 pointedProfileId; uint256 pointedPubId; string contentURI; address referenceModule; address __DEPRECATED__collectModule; // Deprecated in V2 address __DEPRECATED__collectNFT; // Deprecated in V2 // Added in Lens V2, so these will be zero for old publications: PublicationType pubType; uint256 rootProfileId; uint256 rootPubId; // bytes32 __ACTION_MODULE_ENABLED_MAPPING; // Mappings are not supported in memory. } /** * @notice A struct containing the parameters required for the `createProfile()` function. * * @param to The address receiving the profile. * @param followModule The follow module to use, can be the zero address. * @param followModuleInitData The follow module initialization data, if any. */ struct CreateProfileParams { address to; address followModule; bytes followModuleInitData; } /** * @notice A struct containing the parameters required for the `post()` function. * * @param profileId The token ID of the profile to publish to. * @param contentURI The URI to set for this new publication. * @param actionModules The action modules to set for this new publication. * @param actionModulesInitDatas The data to pass to the action modules' initialization. * @param referenceModule The reference module to set for the given publication, must be whitelisted. * @param referenceModuleInitData The data to be passed to the reference module for initialization. */ struct PostParams { uint256 profileId; string contentURI; address[] actionModules; bytes[] actionModulesInitDatas; address referenceModule; bytes referenceModuleInitData; } /** * @notice A struct containing the parameters required for the `comment()` function. * * @param profileId The token ID of the profile to publish to. * @param contentURI The URI to set for this new publication. * @param pointedProfileId The profile token ID to point the comment to. * @param pointedPubId The publication ID to point the comment to. * @param referrerProfileId The profile token ID of the publication that referred to the publication being commented on/quoted. * @param referrerPubId The ID of the publication that referred to the publication being commented on/quoted. * @param referenceModuleData The data passed to the reference module. * @param actionModules The action modules to set for this new publication. * @param actionModulesInitDatas The data to pass to the action modules' initialization. * @param referenceModule The reference module to set for the given publication, must be whitelisted. * @param referenceModuleInitData The data to be passed to the reference module for initialization. */ struct CommentParams { uint256 profileId; string contentURI; uint256 pointedProfileId; uint256 pointedPubId; uint256[] referrerProfileIds; uint256[] referrerPubIds; bytes referenceModuleData; address[] actionModules; bytes[] actionModulesInitDatas; address referenceModule; bytes referenceModuleInitData; } /** * @notice A struct containing the parameters required for the `quote()` function. * * @param profileId The token ID of the profile to publish to. * @param contentURI The URI to set for this new publication. * @param pointedProfileId The profile token ID of the publication author that is quoted. * @param pointedPubId The publication ID that is quoted. * @param referrerProfileId The profile token ID of the publication that referred to the publication being commented on/quoted. * @param referrerPubId The ID of the publication that referred to the publication being commented on/quoted. * @param referenceModuleData The data passed to the reference module. * @param actionModules The action modules to set for this new publication. * @param actionModulesInitDatas The data to pass to the action modules' initialization. * @param referenceModule The reference module to set for the given publication, must be whitelisted. * @param referenceModuleInitData The data to be passed to the reference module for initialization. */ struct QuoteParams { uint256 profileId; string contentURI; uint256 pointedProfileId; uint256 pointedPubId; uint256[] referrerProfileIds; uint256[] referrerPubIds; bytes referenceModuleData; address[] actionModules; bytes[] actionModulesInitDatas; address referenceModule; bytes referenceModuleInitData; } /** * @notice A struct containing the parameters required for the `comment()` or `quote()` internal functions. * * @param profileId The token ID of the profile to publish to. * @param contentURI The URI to set for this new publication. * @param pointedProfileId The profile token ID of the publication author that is commented on/quoted. * @param pointedPubId The publication ID that is commented on/quoted. * @param referrerProfileId The profile token ID of the publication that referred to the publication being commented on/quoted. * @param referrerPubId The ID of the publication that referred to the publication being commented on/quoted. * @param referenceModuleData The data passed to the reference module. * @param actionModules The action modules to set for this new publication. * @param actionModulesInitDatas The data to pass to the action modules' initialization. * @param referenceModule The reference module to set for the given publication, must be whitelisted. * @param referenceModuleInitData The data to be passed to the reference module for initialization. */ struct ReferencePubParams { uint256 profileId; string contentURI; uint256 pointedProfileId; uint256 pointedPubId; uint256[] referrerProfileIds; uint256[] referrerPubIds; bytes referenceModuleData; address[] actionModules; bytes[] actionModulesInitDatas; address referenceModule; bytes referenceModuleInitData; } /** * @notice A struct containing the parameters required for the `mirror()` function. * * @param profileId The token ID of the profile to publish to. * @param metadataURI the URI containing metadata attributes to attach to this mirror publication. * @param pointedProfileId The profile token ID to point the mirror to. * @param pointedPubId The publication ID to point the mirror to. * @param referenceModuleData The data passed to the reference module. */ struct MirrorParams { uint256 profileId; string metadataURI; uint256 pointedProfileId; uint256 pointedPubId; uint256[] referrerProfileIds; uint256[] referrerPubIds; bytes referenceModuleData; } /** * Deprecated in V2: Will be removed after some time after upgrading to V2. * @notice A struct containing the parameters required for the legacy `collect()` function. * @dev The referrer can only be a mirror of the publication being collected. * * @param publicationCollectedProfileId The token ID of the profile that published the publication to collect. * @param publicationCollectedId The publication to collect's publication ID. * @param collectorProfileId The collector profile. * @param referrerProfileId The ID of a profile that authored a mirror that helped discovering the collected pub. * @param referrerPubId The ID of the mirror that helped discovering the collected pub. * @param collectModuleData The arbitrary data to pass to the collectModule if needed. */ struct LegacyCollectParams { uint256 publicationCollectedProfileId; uint256 publicationCollectedId; uint256 collectorProfileId; uint256 referrerProfileId; uint256 referrerPubId; bytes collectModuleData; } /** * @notice A struct containing the parameters required for the `action()` function. * * @param publicationActedProfileId The token ID of the profile that published the publication to action. * @param publicationActedId The publication to action's publication ID. * @param actorProfileId The actor profile. * @param referrerProfileId * @param referrerPubId * @param actionModuleAddress * @param actionModuleData The arbitrary data to pass to the actionModule if needed. */ struct PublicationActionParams { uint256 publicationActedProfileId; uint256 publicationActedId; uint256 actorProfileId; uint256[] referrerProfileIds; uint256[] referrerPubIds; address actionModuleAddress; bytes actionModuleData; } struct ProcessActionParams { uint256 publicationActedProfileId; uint256 publicationActedId; uint256 actorProfileId; address actorProfileOwner; address transactionExecutor; uint256[] referrerProfileIds; uint256[] referrerPubIds; Types.PublicationType[] referrerPubTypes; bytes actionModuleData; } struct ProcessCommentParams { uint256 profileId; uint256 pubId; address transactionExecutor; uint256 pointedProfileId; uint256 pointedPubId; uint256[] referrerProfileIds; uint256[] referrerPubIds; Types.PublicationType[] referrerPubTypes; bytes data; } struct ProcessQuoteParams { uint256 profileId; uint256 pubId; address transactionExecutor; uint256 pointedProfileId; uint256 pointedPubId; uint256[] referrerProfileIds; uint256[] referrerPubIds; Types.PublicationType[] referrerPubTypes; bytes data; } struct ProcessMirrorParams { uint256 profileId; uint256 pubId; address transactionExecutor; uint256 pointedProfileId; uint256 pointedPubId; uint256[] referrerProfileIds; uint256[] referrerPubIds; Types.PublicationType[] referrerPubTypes; bytes data; } /** * @notice A struct containing a profile's delegated executors configuration. * * @param isApproved Tells when an address is approved as delegated executor in the given configuration number. * @param configNumber Current configuration number in use. * @param prevConfigNumber Previous configuration number set, before switching to the current one. * @param maxConfigNumberSet Maximum configuration number ever used. */ struct DelegatedExecutorsConfig { mapping(uint256 => mapping(address => bool)) isApproved; // isApproved[configNumber][delegatedExecutor] uint64 configNumber; uint64 prevConfigNumber; uint64 maxConfigNumberSet; } struct TreasuryData { address treasury; uint16 treasuryFeeBPS; } struct MigrationParams { address lensHandlesAddress; address tokenHandleRegistryAddress; address legacyFeeFollowModule; address legacyProfileFollowModule; address newFeeFollowModule; } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0; import {IERC165} from '@openzeppelin/contracts/utils/introspection/IERC165.sol'; interface ILensModule is IERC165 { /// @dev for now we check for keccak('LENS_MODULE'); /// Override this and add the type(IModuleInterface).interfaceId for corresponding module type function supportsInterface(bytes4 interfaceID) external view returns (bool); /// @notice Human-readable description of the module // Can be JSON // Can be contract source code // Can be github link // Can be ipfs with documentation // etc function getModuleMetadataURI() external view returns (string memory); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.18; import {ILensModule} from 'lens/modules/interfaces/ILensModule.sol'; abstract contract LensModule is ILensModule { /// @inheritdoc ILensModule function supportsInterface(bytes4 interfaceID) public pure virtual override returns (bool) { return interfaceID == bytes4(keccak256(abi.encodePacked('LENS_MODULE'))); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.18; import {Ownable} from '@openzeppelin/contracts/access/Ownable.sol'; import {LensModule} from 'lens/modules/LensModule.sol'; contract LensModuleMetadata is LensModule, Ownable { string public metadataURI; constructor(address owner_) Ownable() { _transferOwnership(owner_); } function setModuleMetadataURI(string memory _metadataURI) external onlyOwner { metadataURI = _metadataURI; } function getModuleMetadataURI() external view returns (string memory) { return metadataURI; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.18; import {LensModuleMetadata} from 'lens/modules/LensModuleMetadata.sol'; contract LensModuleMetadataInitializable is LensModuleMetadata { constructor(address owner_) LensModuleMetadata(owner_) {} function initialize(address moduleOwner) external virtual { if (owner() != address(0) || moduleOwner == address(0)) { revert(); } _transferOwnership(moduleOwner); } }
// SPDX-License-Identifier: MIT /* __/\\\\____________/\\\\_____/\\\\\\\\\_____/\\\\\\\\\\\\_____/\\\\\\\\\\\\\\\__/\\\\\\\\\\\_ _\/\\\\\\________/\\\\\\___/\\\\\\\\\\\\\__\/\\\////////\\\__\/\\\///////////__\/////\\\///__ _\/\\\//\\\____/\\\//\\\__/\\\/////////\\\_\/\\\______\//\\\_\/\\\_________________\/\\\_____ _\/\\\\///\\\/\\\/_\/\\\_\/\\\_______\/\\\_\/\\\_______\/\\\_\/\\\\\\\\\\\_________\/\\\_____ _\/\\\__\///\\\/___\/\\\_\/\\\\\\\\\\\\\\\_\/\\\_______\/\\\_\/\\\///////__________\/\\\_____ _\/\\\____\///_____\/\\\_\/\\\/////////\\\_\/\\\_______\/\\\_\/\\\_________________\/\\\_____ _\/\\\_____________\/\\\_\/\\\_______\/\\\_\/\\\_______/\\\__\/\\\_________________\/\\\_____ _\/\\\_____________\/\\\_\/\\\_______\/\\\_\/\\\\\\\\\\\\/___\/\\\______________/\\\\\\\\\\\_ _\///______________\///__\///________\///__\////////////_____\///______________\///////////__ */ pragma solidity >=0.8.0; import "./ISuperToken.sol"; interface IERC1155 { function balanceOf(address, uint256) external view returns (uint256); } /** * @notice IMadSBT interface * @dev It directly implements ERC721, and supports IERC1155#balanceOf */ interface IMadSBT { struct WrappedCollectionData { address contractAddress; ContractType contractType; uint256 pointedCollectionId; uint256 linkedCollectionId; // if the collection creator makes a regular collection, link them for subgraph } struct CollectionData { uint256 totalSupply; // total tokens minted for a given id uint256 availableSupply; // total tokens available for a given id (0 for no cap) uint256 totalRedeemed; // total tokens redeemed uint256 creatorId; // lens profile id, also the IDA index uint128 totalInterimRewardUnits; // total reward units distributed before minted badges address creatorAddress; // lens profile address string uri; // metadata uri bool isWrapped; // its a pointer to another collection } enum WormholePayloadAction { Mint, Burn } enum ContractType { ERC_721, ERC_1155 } event CreateCollection(address creator, uint256 profileId, uint256 collectionId, uint256 availableSupply); event CreateWrappedCollection(address creator, uint256 profileId, uint256 collectionId); event UpdateRewardUnits(uint256 collectionId, address subscriber, uint128 newUnits); event LinkWrappedCollection(address creator, uint256 profileId, uint256 collectionId, uint256 wrappedCollectionId); event SetCollectionVerifiedAddress(uint256 collectionId, address verifiedAddress, bool verified); function collectionData(uint256) external view returns (uint,uint,uint,uint,uint128,address,string memory,bool); function createCollection(address, uint256, bytes calldata) external returns (uint256); function mint(address, uint256) external returns (uint256); function burn(uint256) external; function redeemInterimRewardUnits(uint256) external; function burnOnSubscriptionCanceled(uint256, address) external; function handleRewardsUpdate(address, uint256, uint8) external; function batchRewardsUpdate(address[] calldata, uint256, uint8, uint128[] calldata) external; function distributeRewards(uint256, uint256) external; function ownerOf(uint256) external view returns (address); function contractURI() external view returns (string memory); function hasMinted(address, uint256) external view returns (bool); function rewardUnitsOf(address, uint256) external view returns (uint128); function totalRewardUnits(uint256) external view returns (uint128); function getLevel(uint256, uint256) external view returns (uint256); function getTokenLevel(uint256) external view returns (uint256); function totalMinted() external view returns (uint256); function subscriptionHandler() external view returns (address); function activeCollection(uint256) external view returns (uint256); function tokenToCollection(uint256) external view returns (uint256); function actionToRewardUnits(uint8) external view returns (uint128); function lensHub() external view returns (address); function rewardsToken() external view returns (ISuperToken); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.10; interface ISuperToken { function getUnderlyingToken() external view returns (address tokenAddr); function upgrade(uint256 amount) external; }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.7.5; pragma abicoder v2; /// @title Router token swapping functionality /// @notice Functions for swapping tokens via Uniswap V3 interface ISwapRouter { struct ExactInputSingleParams { address tokenIn; address tokenOut; uint24 fee; address recipient; uint256 deadline; uint256 amountIn; uint256 amountOutMinimum; uint160 sqrtPriceLimitX96; } struct ExactOutputSingleParams { address tokenIn; address tokenOut; uint24 fee; address recipient; uint256 deadline; uint256 amountOut; uint256 amountInMaximum; uint160 sqrtPriceLimitX96; } /// @notice Swaps `amountIn` of one token for as much as possible of another token /// @param params The parameters necessary for the swap, encoded as `ExactInputSingleParams` in calldata /// @return amountOut The amount of the received token function exactInputSingle(ExactInputSingleParams calldata params) external payable returns (uint256 amountOut); /// @notice Swaps up to `amountInMaximum` of one token for the exact `amountOut` of another token /// @param params The parameters necessary for the swap, encoded as `ExactOutputSingleParams` in calldata /// @return amountIn The necessary amount of the `tokenIn` token needed for the swap function exactOutputSingle(ExactOutputSingleParams calldata params) external payable returns (uint256 amountIn); struct ExactInputParams { bytes path; address recipient; uint256 deadline; uint256 amountIn; uint256 amountOutMinimum; } /// @notice Swaps `amountIn` of one token for as much as possible of another along the specified path /// @param params The parameters necessary for the multi-hop swap, encoded as `ExactInputParams` in calldata /// @return amountOut The amount of the received token function exactInput(ExactInputParams calldata params) external payable returns (uint256 amountOut); } interface IQuoter { /// @notice Returns the amount in required to receive the given exact output amount but for a swap of a single pool /// @param tokenIn The token being swapped in /// @param tokenOut The token being swapped out /// @param fee The fee of the token pool to consider for the pair /// @param amountOut The desired output amount /// @param sqrtPriceLimitX96 The price limit of the pool that cannot be exceeded by the swap /// @return amountIn The amount required as the input for the swap in order to receive amountOut function quoteExactOutputSingle( address tokenIn, address tokenOut, uint24 fee, uint256 amountOut, uint160 sqrtPriceLimitX96 ) external returns (uint256 amountIn); /// @notice Returns the amount out received for a given exact input but for a swap of a single pool /// @param tokenIn The token being swapped in /// @param tokenOut The token being swapped out /// @param fee The fee of the token pool to consider for the pair /// @param amountIn The desired input amount /// @param sqrtPriceLimitX96 The price limit of the pool that cannot be exceeded by the swap function quoteExactInputSingle( address tokenIn, address tokenOut, uint24 fee, uint256 amountIn, uint160 sqrtPriceLimitX96 ) external returns (uint256 amountOut); }
{ "viaIR": true, "optimizer": { "enabled": true, "runs": 2000 }, "evmVersion": "london", "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "metadata": { "useLiteralContent": true }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_uniswapV3Router","type":"address"},{"internalType":"address","name":"_madSBT","type":"address"},{"internalType":"address","name":"_hub","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"BadOutputToken","type":"error"},{"inputs":[{"internalType":"uint16","name":"percentCap","type":"uint16"}],"name":"InvalidPercentCap","type":"error"},{"inputs":[{"internalType":"uint16","name":"percentReward","type":"uint16"}],"name":"InvalidPercentReward","type":"error"},{"inputs":[{"internalType":"uint256","name":"rewardsPoolId","type":"uint256"}],"name":"InvalidRewardsPoolId","type":"error"},{"inputs":[],"name":"NotHub","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"FeesWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"profileId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"pubId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"rewardsPoolId","type":"uint256"}],"name":"PublicationActionInitialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"rewardsPoolId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountOut","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"sharedReward","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"posterReward","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"referrerReward","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"clientReward","type":"uint256"}],"name":"RewardsPaid","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"rewardsPoolId","type":"uint256"},{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"rewardsAmount","type":"uint256"},{"indexed":false,"internalType":"uint16","name":"percentReward","type":"uint16"},{"indexed":false,"internalType":"uint256","name":"cap","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"collectionId","type":"uint256"}],"name":"RewardsPoolCreated","type":"event"},{"inputs":[],"name":"CLIENT_PERCENT","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DIRECT_PROMOTION_SPLIT","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"HUB","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PROTOCOL_FEE","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"rewardsAmount","type":"uint256"},{"internalType":"uint16","name":"percentReward","type":"uint16"},{"internalType":"uint16","name":"percentCap","type":"uint16"},{"internalType":"uint256","name":"profileId","type":"uint256"}],"name":"createRewardsPool","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"path","type":"bytes"}],"name":"extractFinalTokenAddress","outputs":[{"internalType":"address","name":"finalToken","type":"address"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"feesCollected","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getModuleMetadataURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"}],"name":"getSplitsTokenIn","outputs":[{"internalType":"uint256","name":"protocol","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"bool","name":"isDirectPromotion","type":"bool"},{"internalType":"uint256","name":"percentReward","type":"uint256"},{"internalType":"uint256","name":"cap","type":"uint256"},{"internalType":"uint256","name":"remainingRewards","type":"uint256"},{"internalType":"uint256","name":"sharedRewardPercent","type":"uint256"},{"internalType":"bool","name":"isReferral","type":"bool"},{"internalType":"bool","name":"hasClient","type":"bool"}],"name":"getSplitsTokenOut","outputs":[{"internalType":"uint256","name":"poster","type":"uint256"},{"internalType":"uint256","name":"swapper","type":"uint256"},{"internalType":"uint256","name":"referrer","type":"uint256"},{"internalType":"uint256","name":"client","type":"uint256"},{"internalType":"uint256","name":"lens","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"hub","outputs":[{"internalType":"contract ILensHub","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"moduleOwner","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"profileId","type":"uint256"},{"internalType":"uint256","name":"pubId","type":"uint256"},{"internalType":"address","name":"","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"initializePublicationAction","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"madSBT","outputs":[{"internalType":"contract IMadSBT","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"metadataURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"poolCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"posts","outputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"rewardsPoolId","type":"uint256"},{"internalType":"uint16","name":"sharedRewardPercent","type":"uint16"},{"internalType":"address","name":"token","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"publicationActedProfileId","type":"uint256"},{"internalType":"uint256","name":"publicationActedId","type":"uint256"},{"internalType":"uint256","name":"actorProfileId","type":"uint256"},{"internalType":"address","name":"actorProfileOwner","type":"address"},{"internalType":"address","name":"transactionExecutor","type":"address"},{"internalType":"uint256[]","name":"referrerProfileIds","type":"uint256[]"},{"internalType":"uint256[]","name":"referrerPubIds","type":"uint256[]"},{"internalType":"enum Types.PublicationType[]","name":"referrerPubTypes","type":"uint8[]"},{"internalType":"bytes","name":"actionModuleData","type":"bytes"}],"internalType":"struct Types.ProcessActionParams","name":"processActionParams","type":"tuple"}],"name":"processPublicationAction","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"rewardsPools","outputs":[{"internalType":"uint256","name":"rewardsAmount","type":"uint256"},{"internalType":"uint16","name":"percentReward","type":"uint16"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"cap","type":"uint256"},{"internalType":"uint256","name":"collectionId","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"_metadataURI","type":"string"}],"name":"setModuleMetadataURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceID","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"uniswapV3Router","outputs":[{"internalType":"contract ISwapRouter","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"withdrawProtocolFees","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60a034620000dc57601f620026ce38819003918201601f19168301916001600160401b03831184841017620000e157808492606094604052833981010312620000dc576200004d81620000f7565b906200006a60406200006260208401620000f7565b9201620000f7565b8060805262000079336200010c565b62000084336200010c565b60018060a01b0380928160018060a01b03199516856002541617600255168360035416176003551690600454161760045560405161257a9081620001548239608051818181610cfe0152818161169c0152611ba20152f35b600080fd5b634e487b7160e01b600052604160045260246000fd5b51906001600160a01b0382168203620000dc57565b600080546001600160a01b039283166001600160a01b03198216811783559216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09080a356fe6080604052600436101561001257600080fd5b60003560e01c806301ffc9a7146101ad57806303ee438c146101535780630b4501fd1461014e5780630b960220146101a85780632c76d7a6146101a35780632d80caa51461019e57806335ff491614610199578063365a86fc146101945780633d2471b01461018f5780634b4bf12d1461018a5780635b2478ea14610185578063681591c114610180578063715018a61461017b5780638da5cb5b1461017657806390ce6e0814610171578063983fe9201461016c578063a4c52b8614610167578063b6d0753f14610162578063be246e151461015d578063c4d66de814610158578063ce90d52e14610153578063d7cc821c1461014e578063db61ec6114610149578063dc8afbc114610144578063f2fde38b1461013f5763f525cb681461013a57600080fd5b61191c565b611875565b611811565b61179d565b610480565b610378565b611744565b611727565b6116db565b61167c565b611655565b610cc2565b610c9b565b610c34565b610b04565b610a3f565b610765565b6106f0565b6106c9565b61069f565b610548565b610521565b6104ad565b3461026c57602060031936011261026c576004357fffffffff0000000000000000000000000000000000000000000000000000000080821680920361026c57817f9b586c280000000000000000000000000000000000000000000000000000000060209314918215610226575b50506040519015158152f35b909150604051838101907f4c454e535f4d4f44554c450000000000000000000000000000000000000000008252600b8152610260816102e5565b5190201614388061021a565b600080fd5b600091031261026c57565b90600182811c921680156102ac575b602083101461029657565b634e487b7160e01b600052602260045260246000fd5b91607f169161028b565b634e487b7160e01b600052604160045260246000fd5b67ffffffffffffffff81116102e057604052565b6102b6565b6040810190811067ffffffffffffffff8211176102e057604052565b90601f601f19910116810190811067ffffffffffffffff8211176102e057604052565b919082519283825260005b848110610350575050601f19601f8460006020809697860101520116010190565b60208183018101518483018201520161032f565b906020610375928181520190610324565b90565b3461026c5760008060031936011261047d5760405190808260019283549361039f8561027c565b9384845260209586838216918260001461043c5750506001146103e3575b50506103cb92500383610301565b6103df604051928284938452830190610324565b0390f35b908592508082527fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf65b8583106104245750506103cb935082010138806103bd565b8054838901850152879450869390920191810161040c565b915093506103cb9592507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0091501682840152151560051b82010138806103bd565b80fd5b3461026c57600060031936011261026c57602060405160198152f35b6001600160a01b0381160361026c57565b3461026c57608060031936011261026c576104c960443561049c565b67ffffffffffffffff60643581811161026c573660238201121561026c57806004013591821161026c57366024838301011161026c576103df9160246105159201602435600435611b92565b60405191829182610364565b3461026c57600060031936011261026c5760206001600160a01b0360025416604051908152f35b3461026c57602060031936011261026c576004356105658161049c565b61056d61193a565b60009061058182546001600160a01b031690565b6001600160a01b03908183169283156000146105e7575083808080478181156105de575b87871690f1156105d9575b16907fe54a0942fef7ce9447f3f77cd15dbd3b75d25cb88a575aa1e6e22f2dc733b7508380a380f35b611ad6565b506108fc6105a5565b6020818661062961060e61065a956001600160a01b03166000526005602052604060002090565b54926001600160a01b03166000526005602052604060002090565b5560405163a9059cbb60e01b81526001600160a01b0385166004820152602481019190915291829081906044820190565b038188885af180156105d957610671575b506105b0565b6106919060203d8111610698575b6106898183610301565b810190611b7d565b503861066b565b503d61067f565b3461026c57602060031936011261026c5760206127106106c0600435611aa3565b04604051908152f35b3461026c57600060031936011261026c5760206001600160a01b0360045416604051908152f35b3461026c57604060031936011261026c5760043560005260086020526040600020602435600052602052608060406000206001600160a01b0380825416916002600182015491015490604051938452602084015261ffff8116604084015260101c166060820152f35b61ffff81160361026c57565b3461026c5760a060031936011261026c576004356107828161049c565b6044359060243561079283610759565b60643561079e81610759565b608435906127109061ffff8281881611610a0a5781169182116109d357506107c96107d19184611ab4565b612710900490565b90600090806109245750506001600160a01b036000935b6108476107f3610a7d565b85815261ffff881660208201526001600160a01b0383166040820152846060820152866080820152610842610829600654611ae2565b61083281600655565b6000526007602052604060002090565b611af1565b6040517f23b872dd0000000000000000000000000000000000000000000000000000000081523360048201523060248201526044810185905295911692906020866064816000885af19182156105d9576103df967fddb549df4dcf38790c4828a38e8344e11e8e9e71df799f3433ee27afb2e1b43593610906575b506108f3600654968795604051948594859094939261ffff6060936080840197845216602083015260408201520152565b0390a36040519081529081906020820190565b61091d9060203d8111610698576106898183610301565b50386108c2565b60206109849161094b61093f6003546001600160a01b031690565b6001600160a01b031690565b60405180809581947f22872a3f000000000000000000000000000000000000000000000000000000008352600483019190602083019252565b03915afa9081156105d9576001600160a01b0392916109a5575b50936107e8565b6109c6915060203d81116109cc575b6109be8183610301565b810190611ac7565b3861099e565b503d6109b4565b6040517f8e2007cc00000000000000000000000000000000000000000000000000000000815261ffff919091166004820152602490fd5b6040517fc37df07e00000000000000000000000000000000000000000000000000000000815261ffff88166004820152602490fd5b3461026c57602060031936011261026c576001600160a01b03600435610a648161049c565b1660005260056020526020604060002054604051908152f35b6040519060a0820182811067ffffffffffffffff8211176102e057604052565b604051906080820182811067ffffffffffffffff8211176102e057604052565b92919267ffffffffffffffff82116102e05760405191610ae76020601f19601f8401160184610301565b82948184528183011161026c578281602093846000960137010152565b3461026c5760208060031936011261026c5767ffffffffffffffff9060043582811161026c573660238201121561026c57610b49903690602481600401359101610abd565b91610b5261193a565b82519081116102e057600191610b7182610b6c855461027c565b6119e7565b80601f8311600114610bb057508190610ba19394600092610ba5575b50506000198260011b9260031b1c19161790565b9055005b015190503880610b8d565b90601f19831694610be360016000527fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf690565b926000905b878210610c1d57505083859610610c04575b505050811b019055005b015160001960f88460031b161c19169055388080610bfa565b808785968294968601518155019501930190610be8565b3461026c5760008060031936011261047d57610c4e61193a565b806001600160a01b03815473ffffffffffffffffffffffffffffffffffffffff1981168355167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a380f35b3461026c57600060031936011261026c5760206001600160a01b0360005416604051908152f35b3461026c5760031960208136011261026c5767ffffffffffffffff6004351161026c57610120906004353603011261026c576001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016330361162b57610d5e610d59610d44600435600401356000526008602052604060002090565b60246004350135600052602052604060002090565b611e9d565b610d7e610d7960208301516000526007602052604060002090565b611eef565b90610d9f610d9761010460043501600435600401611f48565b810190611f7b565b9193909592610dad826120ec565b946060870192610dc484516001600160a01b031690565b6001600160a01b03811615611609576001600160a01b03905b166001600160a01b038816036115cf57610e6498610e03610dfd83611fc3565b60601c90565b602084610e1460646004350161200d565b6040517f23b872dd0000000000000000000000000000000000000000000000000000000081526001600160a01b03909116600482015230602482015260448101919091529b8c9081906064820190565b038160006001600160a01b0386165af19485156105d957610ed5610ece610f3f9660009e6020996115b2575b50612710610e9d82611aa3565b0490610ebc866001600160a01b03166000526005602052604060002090565b610ec7838254612017565b9055612024565b8093612431565b610edd610a7d565b9384523086850152604084015260608301526080820152610f0961093f6002546001600160a01b031690565b90604051998a809481937fc04b8d5900000000000000000000000000000000000000000000000000000000835260048301612031565b03925af19586156105d957600096611583575b5090610f6b61093f61102f93516001600160a01b031690565b1515610f8160a46004350160043560040161207d565b929050610fd0610f96602087015161ffff1690565b606087015190875190610fae60408c015161ffff1690565b9161ffff938d886001600160a01b038916151596808c1515971695169161226b565b9296939491999095600014611565576001600160a01b0316925b602085610ffe8d516001600160a01b031690565b6040519a8b92839263a9059cbb60e01b845260048401602090939291936001600160a01b0360408201951681520152565b038160006001600160a01b0389165af19788156105d9578c98611546575b50866114ed575b6113cd575b6001600160a01b038116611369575b5080611236575b50506020878101516040805191825291810195909552840192909252606083019190915260808281019490945260a08201527ffabd2f18e29eed301baf43a03e0a7f5e3f2c0db80309e88c626df765ecf441a9908060c081015b0390a10190815190816110fd575b60408051602081018690526103df9161051590829081015b03601f198101835282610301565b61111261093f6003546001600160a01b031690565b9161112160646004350161200d565b92803b1561026c576040517f1333c18b000000000000000000000000000000000000000000000000000000008082526001600160a01b039590951660048201526024810192909252600360448301526000908290606490829084905af180156105d957611223575b506111b06111a261093f6003546001600160a01b031690565b91516001600160a01b031690565b925190803b1561026c576040519283526001600160a01b03939093166004830152602482015260056044820152906000908290606490829084905af180156105d9576103df926110ef926105159261120a575b50926110d7565b8061121761121d926102cc565b80610271565b38611203565b80611217611230926102cc565b38611189565b6004919493929550602061125461093f84546001600160a01b031690565b604051938480927f3b19e84a0000000000000000000000000000000000000000000000000000000082525afa9485156105d9576112d39560209360009161133c575b5060006001600160a01b0360405180998196829563a9059cbb60e01b845260048401602090939291936001600160a01b0360408201951681520152565b0393165af19081156105d9576080967ffabd2f18e29eed301baf43a03e0a7f5e3f2c0db80309e88c626df765ecf441a9958a956110c99461131d575b50925096819394955061106f565b6113359060203d602011610698576106898183610301565b503861130f565b61135c9150843d8611611362575b6113548183610301565b8101906120d7565b38611296565b503d61134a565b60405163a9059cbb60e01b81526001600160a01b0391821660048201526024810186905296506020908790604490829060009087165af19586156105d9578a9615611068576113c69060203d602011610698576106898183610301565b5038611068565b611441965060206113e961093f6004546001600160a01b031690565b61140661140060a46004350160043560040161207d565b906120c9565b359060405180809b81947f6352211e000000000000000000000000000000000000000000000000000000008352600483019190602083019252565b03915afa80156105d9578960209161148d996000916114d0575b50604051998a92839263a9059cbb60e01b845260048401602090939291936001600160a01b0360408201951681520152565b038160006001600160a01b0388165af19687156105d9578b976114b1575b50611059565b6114c99060203d602011610698576106898183610301565b50386114ab565b6114e79150833d8511611362576113548183610301565b3861145b565b6115039750602087610ffe60646004350161200d565b038160006001600160a01b0389165af19788156105d9578c98611527575b50611054565b61153f9060203d602011610698576106898183610301565b5038611521565b61155e9060203d602011610698576106898183610301565b503861104d565b5061157d61093f60408a01516001600160a01b031690565b92610fea565b61102f9291965061093f6115a8610f6b9260203d6020116109cc576109be8183610301565b9792935050610f52565b6115c8908a3d8c11610698576106898183610301565b5038610e90565b6040517fb7af61e80000000000000000000000000000000000000000000000000000000081526001600160a01b0388166004820152602490fd5b506001600160a01b0361162660408801516001600160a01b031690565b610ddd565b60046040517f9de97418000000000000000000000000000000000000000000000000000000008152fd5b3461026c57600060031936011261026c5760206001600160a01b0360035416604051908152f35b3461026c57600060031936011261026c5760206040516001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168152f35b9080601f8301121561026c5781602061037593359101610abd565b3461026c57602060031936011261026c5760043567ffffffffffffffff811161026c5761171661171160209236906004016116c0565b6120ec565b6001600160a01b0360405191168152f35b3461026c57600060031936011261026c5760206040516101f48152f35b3461026c57602060031936011261026c576004356117618161049c565b6001600160a01b0380600054161590811591611788575b5061026c5761178690611992565b005b905081161538611778565b8015150361026c57565b3461026c5761010060031936011261026c5760a06117f16024356117c081611793565b60c4356117cc81611793565b60e435916117d983611793565b60a4359060843590606435906044359060043561226b565b926040929192519485526020850152604084015260608301526080820152f35b3461026c57602060031936011261026c57600435600052600760205260a060406000208054906001810154906001600160a01b03600360028301549201549260405194855261ffff8116602086015260101c16604084015260608301526080820152f35b3461026c57602060031936011261026c576004356118928161049c565b61189a61193a565b6001600160a01b038116156118b25761178690611992565b608460405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152fd5b3461026c57600060031936011261026c576020600654604051908152f35b6001600160a01b0360005416330361194e57565b606460405162461bcd60e51b815260206004820152602060248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152fd5b600054906001600160a01b03809116918273ffffffffffffffffffffffffffffffffffffffff19821617600055167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0600080a3565b90601f82116119f4575050565b6001916000908382527fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6906020601f850160051c83019410611a51575b601f0160051c01915b828110611a475750505050565b8181558301611a3a565b9092508290611a31565b634e487b7160e01b600052601160045260246000fd5b906101f491828102928184041490151715611a8857565b611a5b565b90601982029180830460191490151715611a8857565b9081601902916019830403611a8857565b81810292918115918404141715611a8857565b9081602091031261026c575190565b6040513d6000823e3d90fd5b6000198114611a885760010190565b90608060039180518455611b6c60018501611b2061ffff602085015116829061ffff1661ffff19825416179055565b604083015181547fffffffffffffffffffff0000000000000000000000000000000000000000ffff1660109190911b75ffffffffffffffffffffffffffffffffffffffff000016179055565b606081015160028501550151910155565b9081602091031261026c575161037581611793565b919290926001600160a01b0391827f000000000000000000000000000000000000000000000000000000000000000016330361162b5781611bd69184930190611d8b565b919592949095169261271061ffff861611611d5657801580611d43575b611d1157917fc2502ea09f438f6a9e5d88670e18b36286a40bb5785fb5bfd6e0d4bab7255ec9959391611cad9593600014611cb85790611c7191611c60611c9d95611c4e611c3f610a9d565b6001600160a01b039097168752565b6000602087015261ffff166040860152565b166001600160a01b03166060830152565b611c9887611c89886000526008602052604060002090565b90600052602052604060002090565b611dd3565b6040519081529081906020820190565b0390a3610375611e79565b5050611ced611d0c92611cdb611ccc610a9d565b6001600160a01b039094168452565b6020830185905261ffff166040830152565b60006060820152611c9887611c89886000526008602052604060002090565b611c9d565b6040517fc3e081e000000000000000000000000000000000000000000000000000000000815260048101879052602490fd5b50600654861180611bf357508515611bf3565b6040517fc37df07e00000000000000000000000000000000000000000000000000000000815261ffff86166004820152602490fd5b908160a091031261026c578035611da181611793565b916020820135611db081610759565b916040810135611dbf8161049c565b91608060608301359201356103758161049c565b90611e7791606060026001600160a01b03928385511673ffffffffffffffffffffffffffffffffffffffff19825416178155602085015160018201550192611e2f61ffff604083015116859061ffff1661ffff19825416179055565b015182547fffffffffffffffffffff0000000000000000000000000000000000000000ffff16911660101b75ffffffffffffffffffffffffffffffffffffffff000016179055565b565b604051906020820182811067ffffffffffffffff8211176102e05760405260008252565b906040516080810181811067ffffffffffffffff8211176102e0576040526060819360026001600160a01b039182815416855260018101546020860152015461ffff8116604085015260101c16910152565b9060405160a0810181811067ffffffffffffffff8211176102e057604052608060038294805484526001600160a01b03600182015461ffff8116602087015260101c166040850152600281015460608501520154910152565b903590601e198136030182121561026c570180359067ffffffffffffffff821161026c5760200191813603831361026c57565b9060a08282031261026c5781359067ffffffffffffffff821161026c57611fa39183016116c0565b91602082013591604081013591608060608301359201356103758161049c565b90602082519201517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000908181169360148110611ffe57505050565b60140360031b82901b16169150565b356103758161049c565b91908201809211611a8857565b91908203918211611a8857565b6020815260a0608061204e845183602086015260c0850190610324565b936001600160a01b03602082015116604085015260408101516060850152606081015182850152015191015290565b903590601e198136030182121561026c570180359067ffffffffffffffff821161026c57602001918160051b3603831361026c57565b634e487b7160e01b600052603260045260246000fd5b90156120d25790565b6120b3565b9081602091031261026c57516103758161049c565b90601491828151106121ad578051927fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec918483810111611a885760405192612133846102e5565b82845260203681860137600095865b848110612159575050505050610375919250612202565b828282010190818111611a88577fff000000000000000000000000000000000000000000000000000000000000006121946121a893876121f1565b5116891a6121a282896121f1565b53611ae2565b612142565b606460405162461bcd60e51b815260206004820152600e60248201527f5061746820746f6f2073686f72740000000000000000000000000000000000006044820152fd5b9081518110156120d2570160200190565b6014815103612212576014015190565b606460405162461bcd60e51b815260206004820152601360248201527f496e76616c69642064617461206c656e677468000000000000000000000000006044820152fd5b9081602091031261026c575161037581610759565b9593909492916004602061228961093f83546001600160a01b031690565b604051928380927f29070c6d0000000000000000000000000000000000000000000000000000000082525afa80156105d95761ffff91600091612403575b5016951561234157505050506122e96122e26107c985611a8d565b8094612024565b936000901561233757506123226123026107c985611a71565b935b61231c6123156107c9879684611ab4565b8096612017565b90612024565b90156123305760011c918294565b9160009294565b6123229093612304565b6123bf926107c999986123ad9695936123606107c96123ad958c611ab4565b928084116123fb575b508083116123f3575b50600090156123e457506123ad6123b761238e6107c984611a71565b9b8c955b6123b26123a36107c9899d88611ab4565b809b819988612024565b612024565b611ab4565b9a8b92612024565b90156123d7576123d49060011c938496612017565b93565b946000936123d491612017565b6123b76123ad919b8c95612392565b915038612372565b925038612369565b612424915060203d811161242a575b61241c8183610301565b810190612256565b386122c7565b503d612412565b6001600160a01b031661244f61093f6002546001600160a01b031690565b6040517fdd62ed3e0000000000000000000000000000000000000000000000000000000081523060048201526001600160a01b0382166024820152602093919291908481604481865afa9081156105d957600091612527575b50106124b357505050565b6040517f095ea7b30000000000000000000000000000000000000000000000000000000081526001600160a01b0392909216600483015260001960248301528290829060449082906000905af180156105d95761250e575050565b8161252492903d10610698576106898183610301565b50565b61253e9150853d87116109cc576109be8183610301565b386124a856fea2646970667358221220edd30e622b1aad1540a8bc59544ee9a2140123a181ba604287c494a405f33b5964736f6c63430008150033000000000000000000000000e592427a0aece92de3edee1f18e0157c0586156400000000000000000000000022209d6eae6ceba2d059ebfe67b67837bcc1b428000000000000000000000000db46d1dc155634fbc732f92e853b10b288ad5a1d
Deployed Bytecode
0x6080604052600436101561001257600080fd5b60003560e01c806301ffc9a7146101ad57806303ee438c146101535780630b4501fd1461014e5780630b960220146101a85780632c76d7a6146101a35780632d80caa51461019e57806335ff491614610199578063365a86fc146101945780633d2471b01461018f5780634b4bf12d1461018a5780635b2478ea14610185578063681591c114610180578063715018a61461017b5780638da5cb5b1461017657806390ce6e0814610171578063983fe9201461016c578063a4c52b8614610167578063b6d0753f14610162578063be246e151461015d578063c4d66de814610158578063ce90d52e14610153578063d7cc821c1461014e578063db61ec6114610149578063dc8afbc114610144578063f2fde38b1461013f5763f525cb681461013a57600080fd5b61191c565b611875565b611811565b61179d565b610480565b610378565b611744565b611727565b6116db565b61167c565b611655565b610cc2565b610c9b565b610c34565b610b04565b610a3f565b610765565b6106f0565b6106c9565b61069f565b610548565b610521565b6104ad565b3461026c57602060031936011261026c576004357fffffffff0000000000000000000000000000000000000000000000000000000080821680920361026c57817f9b586c280000000000000000000000000000000000000000000000000000000060209314918215610226575b50506040519015158152f35b909150604051838101907f4c454e535f4d4f44554c450000000000000000000000000000000000000000008252600b8152610260816102e5565b5190201614388061021a565b600080fd5b600091031261026c57565b90600182811c921680156102ac575b602083101461029657565b634e487b7160e01b600052602260045260246000fd5b91607f169161028b565b634e487b7160e01b600052604160045260246000fd5b67ffffffffffffffff81116102e057604052565b6102b6565b6040810190811067ffffffffffffffff8211176102e057604052565b90601f601f19910116810190811067ffffffffffffffff8211176102e057604052565b919082519283825260005b848110610350575050601f19601f8460006020809697860101520116010190565b60208183018101518483018201520161032f565b906020610375928181520190610324565b90565b3461026c5760008060031936011261047d5760405190808260019283549361039f8561027c565b9384845260209586838216918260001461043c5750506001146103e3575b50506103cb92500383610301565b6103df604051928284938452830190610324565b0390f35b908592508082527fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf65b8583106104245750506103cb935082010138806103bd565b8054838901850152879450869390920191810161040c565b915093506103cb9592507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0091501682840152151560051b82010138806103bd565b80fd5b3461026c57600060031936011261026c57602060405160198152f35b6001600160a01b0381160361026c57565b3461026c57608060031936011261026c576104c960443561049c565b67ffffffffffffffff60643581811161026c573660238201121561026c57806004013591821161026c57366024838301011161026c576103df9160246105159201602435600435611b92565b60405191829182610364565b3461026c57600060031936011261026c5760206001600160a01b0360025416604051908152f35b3461026c57602060031936011261026c576004356105658161049c565b61056d61193a565b60009061058182546001600160a01b031690565b6001600160a01b03908183169283156000146105e7575083808080478181156105de575b87871690f1156105d9575b16907fe54a0942fef7ce9447f3f77cd15dbd3b75d25cb88a575aa1e6e22f2dc733b7508380a380f35b611ad6565b506108fc6105a5565b6020818661062961060e61065a956001600160a01b03166000526005602052604060002090565b54926001600160a01b03166000526005602052604060002090565b5560405163a9059cbb60e01b81526001600160a01b0385166004820152602481019190915291829081906044820190565b038188885af180156105d957610671575b506105b0565b6106919060203d8111610698575b6106898183610301565b810190611b7d565b503861066b565b503d61067f565b3461026c57602060031936011261026c5760206127106106c0600435611aa3565b04604051908152f35b3461026c57600060031936011261026c5760206001600160a01b0360045416604051908152f35b3461026c57604060031936011261026c5760043560005260086020526040600020602435600052602052608060406000206001600160a01b0380825416916002600182015491015490604051938452602084015261ffff8116604084015260101c166060820152f35b61ffff81160361026c57565b3461026c5760a060031936011261026c576004356107828161049c565b6044359060243561079283610759565b60643561079e81610759565b608435906127109061ffff8281881611610a0a5781169182116109d357506107c96107d19184611ab4565b612710900490565b90600090806109245750506001600160a01b036000935b6108476107f3610a7d565b85815261ffff881660208201526001600160a01b0383166040820152846060820152866080820152610842610829600654611ae2565b61083281600655565b6000526007602052604060002090565b611af1565b6040517f23b872dd0000000000000000000000000000000000000000000000000000000081523360048201523060248201526044810185905295911692906020866064816000885af19182156105d9576103df967fddb549df4dcf38790c4828a38e8344e11e8e9e71df799f3433ee27afb2e1b43593610906575b506108f3600654968795604051948594859094939261ffff6060936080840197845216602083015260408201520152565b0390a36040519081529081906020820190565b61091d9060203d8111610698576106898183610301565b50386108c2565b60206109849161094b61093f6003546001600160a01b031690565b6001600160a01b031690565b60405180809581947f22872a3f000000000000000000000000000000000000000000000000000000008352600483019190602083019252565b03915afa9081156105d9576001600160a01b0392916109a5575b50936107e8565b6109c6915060203d81116109cc575b6109be8183610301565b810190611ac7565b3861099e565b503d6109b4565b6040517f8e2007cc00000000000000000000000000000000000000000000000000000000815261ffff919091166004820152602490fd5b6040517fc37df07e00000000000000000000000000000000000000000000000000000000815261ffff88166004820152602490fd5b3461026c57602060031936011261026c576001600160a01b03600435610a648161049c565b1660005260056020526020604060002054604051908152f35b6040519060a0820182811067ffffffffffffffff8211176102e057604052565b604051906080820182811067ffffffffffffffff8211176102e057604052565b92919267ffffffffffffffff82116102e05760405191610ae76020601f19601f8401160184610301565b82948184528183011161026c578281602093846000960137010152565b3461026c5760208060031936011261026c5767ffffffffffffffff9060043582811161026c573660238201121561026c57610b49903690602481600401359101610abd565b91610b5261193a565b82519081116102e057600191610b7182610b6c855461027c565b6119e7565b80601f8311600114610bb057508190610ba19394600092610ba5575b50506000198260011b9260031b1c19161790565b9055005b015190503880610b8d565b90601f19831694610be360016000527fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf690565b926000905b878210610c1d57505083859610610c04575b505050811b019055005b015160001960f88460031b161c19169055388080610bfa565b808785968294968601518155019501930190610be8565b3461026c5760008060031936011261047d57610c4e61193a565b806001600160a01b03815473ffffffffffffffffffffffffffffffffffffffff1981168355167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a380f35b3461026c57600060031936011261026c5760206001600160a01b0360005416604051908152f35b3461026c5760031960208136011261026c5767ffffffffffffffff6004351161026c57610120906004353603011261026c576001600160a01b037f000000000000000000000000db46d1dc155634fbc732f92e853b10b288ad5a1d16330361162b57610d5e610d59610d44600435600401356000526008602052604060002090565b60246004350135600052602052604060002090565b611e9d565b610d7e610d7960208301516000526007602052604060002090565b611eef565b90610d9f610d9761010460043501600435600401611f48565b810190611f7b565b9193909592610dad826120ec565b946060870192610dc484516001600160a01b031690565b6001600160a01b03811615611609576001600160a01b03905b166001600160a01b038816036115cf57610e6498610e03610dfd83611fc3565b60601c90565b602084610e1460646004350161200d565b6040517f23b872dd0000000000000000000000000000000000000000000000000000000081526001600160a01b03909116600482015230602482015260448101919091529b8c9081906064820190565b038160006001600160a01b0386165af19485156105d957610ed5610ece610f3f9660009e6020996115b2575b50612710610e9d82611aa3565b0490610ebc866001600160a01b03166000526005602052604060002090565b610ec7838254612017565b9055612024565b8093612431565b610edd610a7d565b9384523086850152604084015260608301526080820152610f0961093f6002546001600160a01b031690565b90604051998a809481937fc04b8d5900000000000000000000000000000000000000000000000000000000835260048301612031565b03925af19586156105d957600096611583575b5090610f6b61093f61102f93516001600160a01b031690565b1515610f8160a46004350160043560040161207d565b929050610fd0610f96602087015161ffff1690565b606087015190875190610fae60408c015161ffff1690565b9161ffff938d886001600160a01b038916151596808c1515971695169161226b565b9296939491999095600014611565576001600160a01b0316925b602085610ffe8d516001600160a01b031690565b6040519a8b92839263a9059cbb60e01b845260048401602090939291936001600160a01b0360408201951681520152565b038160006001600160a01b0389165af19788156105d9578c98611546575b50866114ed575b6113cd575b6001600160a01b038116611369575b5080611236575b50506020878101516040805191825291810195909552840192909252606083019190915260808281019490945260a08201527ffabd2f18e29eed301baf43a03e0a7f5e3f2c0db80309e88c626df765ecf441a9908060c081015b0390a10190815190816110fd575b60408051602081018690526103df9161051590829081015b03601f198101835282610301565b61111261093f6003546001600160a01b031690565b9161112160646004350161200d565b92803b1561026c576040517f1333c18b000000000000000000000000000000000000000000000000000000008082526001600160a01b039590951660048201526024810192909252600360448301526000908290606490829084905af180156105d957611223575b506111b06111a261093f6003546001600160a01b031690565b91516001600160a01b031690565b925190803b1561026c576040519283526001600160a01b03939093166004830152602482015260056044820152906000908290606490829084905af180156105d9576103df926110ef926105159261120a575b50926110d7565b8061121761121d926102cc565b80610271565b38611203565b80611217611230926102cc565b38611189565b6004919493929550602061125461093f84546001600160a01b031690565b604051938480927f3b19e84a0000000000000000000000000000000000000000000000000000000082525afa9485156105d9576112d39560209360009161133c575b5060006001600160a01b0360405180998196829563a9059cbb60e01b845260048401602090939291936001600160a01b0360408201951681520152565b0393165af19081156105d9576080967ffabd2f18e29eed301baf43a03e0a7f5e3f2c0db80309e88c626df765ecf441a9958a956110c99461131d575b50925096819394955061106f565b6113359060203d602011610698576106898183610301565b503861130f565b61135c9150843d8611611362575b6113548183610301565b8101906120d7565b38611296565b503d61134a565b60405163a9059cbb60e01b81526001600160a01b0391821660048201526024810186905296506020908790604490829060009087165af19586156105d9578a9615611068576113c69060203d602011610698576106898183610301565b5038611068565b611441965060206113e961093f6004546001600160a01b031690565b61140661140060a46004350160043560040161207d565b906120c9565b359060405180809b81947f6352211e000000000000000000000000000000000000000000000000000000008352600483019190602083019252565b03915afa80156105d9578960209161148d996000916114d0575b50604051998a92839263a9059cbb60e01b845260048401602090939291936001600160a01b0360408201951681520152565b038160006001600160a01b0388165af19687156105d9578b976114b1575b50611059565b6114c99060203d602011610698576106898183610301565b50386114ab565b6114e79150833d8511611362576113548183610301565b3861145b565b6115039750602087610ffe60646004350161200d565b038160006001600160a01b0389165af19788156105d9578c98611527575b50611054565b61153f9060203d602011610698576106898183610301565b5038611521565b61155e9060203d602011610698576106898183610301565b503861104d565b5061157d61093f60408a01516001600160a01b031690565b92610fea565b61102f9291965061093f6115a8610f6b9260203d6020116109cc576109be8183610301565b9792935050610f52565b6115c8908a3d8c11610698576106898183610301565b5038610e90565b6040517fb7af61e80000000000000000000000000000000000000000000000000000000081526001600160a01b0388166004820152602490fd5b506001600160a01b0361162660408801516001600160a01b031690565b610ddd565b60046040517f9de97418000000000000000000000000000000000000000000000000000000008152fd5b3461026c57600060031936011261026c5760206001600160a01b0360035416604051908152f35b3461026c57600060031936011261026c5760206040516001600160a01b037f000000000000000000000000db46d1dc155634fbc732f92e853b10b288ad5a1d168152f35b9080601f8301121561026c5781602061037593359101610abd565b3461026c57602060031936011261026c5760043567ffffffffffffffff811161026c5761171661171160209236906004016116c0565b6120ec565b6001600160a01b0360405191168152f35b3461026c57600060031936011261026c5760206040516101f48152f35b3461026c57602060031936011261026c576004356117618161049c565b6001600160a01b0380600054161590811591611788575b5061026c5761178690611992565b005b905081161538611778565b8015150361026c57565b3461026c5761010060031936011261026c5760a06117f16024356117c081611793565b60c4356117cc81611793565b60e435916117d983611793565b60a4359060843590606435906044359060043561226b565b926040929192519485526020850152604084015260608301526080820152f35b3461026c57602060031936011261026c57600435600052600760205260a060406000208054906001810154906001600160a01b03600360028301549201549260405194855261ffff8116602086015260101c16604084015260608301526080820152f35b3461026c57602060031936011261026c576004356118928161049c565b61189a61193a565b6001600160a01b038116156118b25761178690611992565b608460405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152fd5b3461026c57600060031936011261026c576020600654604051908152f35b6001600160a01b0360005416330361194e57565b606460405162461bcd60e51b815260206004820152602060248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152fd5b600054906001600160a01b03809116918273ffffffffffffffffffffffffffffffffffffffff19821617600055167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0600080a3565b90601f82116119f4575050565b6001916000908382527fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6906020601f850160051c83019410611a51575b601f0160051c01915b828110611a475750505050565b8181558301611a3a565b9092508290611a31565b634e487b7160e01b600052601160045260246000fd5b906101f491828102928184041490151715611a8857565b611a5b565b90601982029180830460191490151715611a8857565b9081601902916019830403611a8857565b81810292918115918404141715611a8857565b9081602091031261026c575190565b6040513d6000823e3d90fd5b6000198114611a885760010190565b90608060039180518455611b6c60018501611b2061ffff602085015116829061ffff1661ffff19825416179055565b604083015181547fffffffffffffffffffff0000000000000000000000000000000000000000ffff1660109190911b75ffffffffffffffffffffffffffffffffffffffff000016179055565b606081015160028501550151910155565b9081602091031261026c575161037581611793565b919290926001600160a01b0391827f000000000000000000000000db46d1dc155634fbc732f92e853b10b288ad5a1d16330361162b5781611bd69184930190611d8b565b919592949095169261271061ffff861611611d5657801580611d43575b611d1157917fc2502ea09f438f6a9e5d88670e18b36286a40bb5785fb5bfd6e0d4bab7255ec9959391611cad9593600014611cb85790611c7191611c60611c9d95611c4e611c3f610a9d565b6001600160a01b039097168752565b6000602087015261ffff166040860152565b166001600160a01b03166060830152565b611c9887611c89886000526008602052604060002090565b90600052602052604060002090565b611dd3565b6040519081529081906020820190565b0390a3610375611e79565b5050611ced611d0c92611cdb611ccc610a9d565b6001600160a01b039094168452565b6020830185905261ffff166040830152565b60006060820152611c9887611c89886000526008602052604060002090565b611c9d565b6040517fc3e081e000000000000000000000000000000000000000000000000000000000815260048101879052602490fd5b50600654861180611bf357508515611bf3565b6040517fc37df07e00000000000000000000000000000000000000000000000000000000815261ffff86166004820152602490fd5b908160a091031261026c578035611da181611793565b916020820135611db081610759565b916040810135611dbf8161049c565b91608060608301359201356103758161049c565b90611e7791606060026001600160a01b03928385511673ffffffffffffffffffffffffffffffffffffffff19825416178155602085015160018201550192611e2f61ffff604083015116859061ffff1661ffff19825416179055565b015182547fffffffffffffffffffff0000000000000000000000000000000000000000ffff16911660101b75ffffffffffffffffffffffffffffffffffffffff000016179055565b565b604051906020820182811067ffffffffffffffff8211176102e05760405260008252565b906040516080810181811067ffffffffffffffff8211176102e0576040526060819360026001600160a01b039182815416855260018101546020860152015461ffff8116604085015260101c16910152565b9060405160a0810181811067ffffffffffffffff8211176102e057604052608060038294805484526001600160a01b03600182015461ffff8116602087015260101c166040850152600281015460608501520154910152565b903590601e198136030182121561026c570180359067ffffffffffffffff821161026c5760200191813603831361026c57565b9060a08282031261026c5781359067ffffffffffffffff821161026c57611fa39183016116c0565b91602082013591604081013591608060608301359201356103758161049c565b90602082519201517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000908181169360148110611ffe57505050565b60140360031b82901b16169150565b356103758161049c565b91908201809211611a8857565b91908203918211611a8857565b6020815260a0608061204e845183602086015260c0850190610324565b936001600160a01b03602082015116604085015260408101516060850152606081015182850152015191015290565b903590601e198136030182121561026c570180359067ffffffffffffffff821161026c57602001918160051b3603831361026c57565b634e487b7160e01b600052603260045260246000fd5b90156120d25790565b6120b3565b9081602091031261026c57516103758161049c565b90601491828151106121ad578051927fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec918483810111611a885760405192612133846102e5565b82845260203681860137600095865b848110612159575050505050610375919250612202565b828282010190818111611a88577fff000000000000000000000000000000000000000000000000000000000000006121946121a893876121f1565b5116891a6121a282896121f1565b53611ae2565b612142565b606460405162461bcd60e51b815260206004820152600e60248201527f5061746820746f6f2073686f72740000000000000000000000000000000000006044820152fd5b9081518110156120d2570160200190565b6014815103612212576014015190565b606460405162461bcd60e51b815260206004820152601360248201527f496e76616c69642064617461206c656e677468000000000000000000000000006044820152fd5b9081602091031261026c575161037581610759565b9593909492916004602061228961093f83546001600160a01b031690565b604051928380927f29070c6d0000000000000000000000000000000000000000000000000000000082525afa80156105d95761ffff91600091612403575b5016951561234157505050506122e96122e26107c985611a8d565b8094612024565b936000901561233757506123226123026107c985611a71565b935b61231c6123156107c9879684611ab4565b8096612017565b90612024565b90156123305760011c918294565b9160009294565b6123229093612304565b6123bf926107c999986123ad9695936123606107c96123ad958c611ab4565b928084116123fb575b508083116123f3575b50600090156123e457506123ad6123b761238e6107c984611a71565b9b8c955b6123b26123a36107c9899d88611ab4565b809b819988612024565b612024565b611ab4565b9a8b92612024565b90156123d7576123d49060011c938496612017565b93565b946000936123d491612017565b6123b76123ad919b8c95612392565b915038612372565b925038612369565b612424915060203d811161242a575b61241c8183610301565b810190612256565b386122c7565b503d612412565b6001600160a01b031661244f61093f6002546001600160a01b031690565b6040517fdd62ed3e0000000000000000000000000000000000000000000000000000000081523060048201526001600160a01b0382166024820152602093919291908481604481865afa9081156105d957600091612527575b50106124b357505050565b6040517f095ea7b30000000000000000000000000000000000000000000000000000000081526001600160a01b0392909216600483015260001960248301528290829060449082906000905af180156105d95761250e575050565b8161252492903d10610698576106898183610301565b50565b61253e9150853d87116109cc576109be8183610301565b386124a856fea2646970667358221220edd30e622b1aad1540a8bc59544ee9a2140123a181ba604287c494a405f33b5964736f6c63430008150033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000e592427a0aece92de3edee1f18e0157c0586156400000000000000000000000022209d6eae6ceba2d059ebfe67b67837bcc1b428000000000000000000000000db46d1dc155634fbc732f92e853b10b288ad5a1d
-----Decoded View---------------
Arg [0] : _uniswapV3Router (address): 0xE592427A0AEce92De3Edee1F18E0157C05861564
Arg [1] : _madSBT (address): 0x22209D6eAe6cEBA2d059ebfE67b67837BCC1b428
Arg [2] : _hub (address): 0xDb46d1Dc155634FbC732f92E853b10B288AD5a1d
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 000000000000000000000000e592427a0aece92de3edee1f18e0157c05861564
Arg [1] : 00000000000000000000000022209d6eae6ceba2d059ebfe67b67837bcc1b428
Arg [2] : 000000000000000000000000db46d1dc155634fbc732f92e853b10b288ad5a1d
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.