ETH Price: $2,858.56 (-2.81%)

Contract

0x2b7e7Aa4120aB81361C46CB5f3dC879de5D85dfd

Overview

ETH Balance

0 ETH

ETH Value

$0.00

Token Holdings

More Info

Private Name Tags

Multichain Info

No addresses found
Transaction Hash
Block
From
To
Claim3603930732025-07-22 13:33:40187 days ago1753191220IN
0x2b7e7Aa4...de5D85dfd
0 ETH0.000013080.046799
Claim3540467882025-07-04 4:41:21205 days ago1751604081IN
0x2b7e7Aa4...de5D85dfd
0 ETH0.000002790.01
Claim3533407852025-07-02 3:34:11208 days ago1751427251IN
0x2b7e7Aa4...de5D85dfd
0 ETH0.000002220.01
Claim3533364492025-07-02 3:16:08208 days ago1751426168IN
0x2b7e7Aa4...de5D85dfd
0 ETH0.000002050.01
Claim3519490472025-06-28 2:47:19212 days ago1751078839IN
0x2b7e7Aa4...de5D85dfd
0 ETH0.000002830.01
Claim3434780582025-06-03 12:42:05236 days ago1748954525IN
0x2b7e7Aa4...de5D85dfd
0 ETH0.000002870.01
Claim3349741472025-05-09 19:10:03261 days ago1746817803IN
0x2b7e7Aa4...de5D85dfd
0 ETH0.000002920.01
Claim3152323012025-03-13 10:52:46318 days ago1741863166IN
0x2b7e7Aa4...de5D85dfd
0 ETH0.000003230.011365
Claim3075846912025-02-19 5:13:38340 days ago1739942018IN
0x2b7e7Aa4...de5D85dfd
0 ETH0.000002810.01
Claim3073193682025-02-18 10:43:31341 days ago1739875411IN
0x2b7e7Aa4...de5D85dfd
0 ETH0.000003080.01
Claim3016881062025-02-02 0:32:17358 days ago1738456337IN
0x2b7e7Aa4...de5D85dfd
0 ETH0.000002860.01
Claim2989177882025-01-24 22:00:38366 days ago1737756038IN
0x2b7e7Aa4...de5D85dfd
0 ETH0.000002650.01
Claim2980511952025-01-22 9:54:31368 days ago1737539671IN
0x2b7e7Aa4...de5D85dfd
0 ETH0.000003060.01
Claim2977833532025-01-21 15:13:25369 days ago1737472405IN
0x2b7e7Aa4...de5D85dfd
0 ETH0.000016980.05879
Claim2974776152025-01-20 17:55:19370 days ago1737395719IN
0x2b7e7Aa4...de5D85dfd
0 ETH0.000369291.258518
Claim2970960612025-01-19 15:21:20371 days ago1737300080IN
0x2b7e7Aa4...de5D85dfd
0 ETH0.000032260.105978
Claim2960812292025-01-16 16:30:15374 days ago1737045015IN
0x2b7e7Aa4...de5D85dfd
0 ETH0.000021130.01
Claim2959113382025-01-16 4:39:46374 days ago1737002386IN
0x2b7e7Aa4...de5D85dfd
0 ETH0.000002860.01
Claim2955495872025-01-15 3:28:42376 days ago1736911722IN
0x2b7e7Aa4...de5D85dfd
0 ETH0.000005620.01
Claim2954364632025-01-14 19:35:03376 days ago1736883303IN
0x2b7e7Aa4...de5D85dfd
0 ETH0.000003450.01
Claim2954357782025-01-14 19:32:12376 days ago1736883132IN
0x2b7e7Aa4...de5D85dfd
0 ETH0.000003980.01
Claim2954350192025-01-14 19:29:01376 days ago1736882941IN
0x2b7e7Aa4...de5D85dfd
0 ETH0.0000040.01
Claim2954345322025-01-14 19:26:58376 days ago1736882818IN
0x2b7e7Aa4...de5D85dfd
0 ETH0.000003930.01
Claim2953595452025-01-14 14:13:50376 days ago1736864030IN
0x2b7e7Aa4...de5D85dfd
0 ETH0.000002630.01
Claim2936515272025-01-09 14:59:49381 days ago1736434789IN
0x2b7e7Aa4...de5D85dfd
0 ETH0.000005150.01
View all transactions

Latest 1 internal transaction

Parent Transaction Hash Block From To
2878207032024-12-23 16:11:49398 days ago1734970309  Contract Creation0 ETH

Cross-Chain Transactions
Loading...
Loading

Minimal Proxy Contract for 0x6a1d83666ef16c538b500d38493d7e4e1ae55263

Contract Name:
PearStakingAirdrop

Compiler Version
v0.8.20+commit.a1b79de6

Optimization Enabled:
Yes with 2000 runs

Other Settings:
paris EvmVersion

Contract Source Code (Solidity Standard Json-Input format)

// SPDX-License-Identifier: MIT
pragma solidity 0.8.20;

import { IPearStaker } from "../interfaces/IPearStaker.sol";
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import { IERC721 } from "@openzeppelin/contracts/token/ERC721/IERC721.sol";
import { Errors } from "../libraries/Errors.sol";
import { Events } from "../libraries/Events.sol";
import { ComptrollerManager } from "../helpers/ComptrollerManager.sol";
import { Initializable } from
    "@openzeppelin-upgradeable/contracts/proxy/utils/Initializable.sol";
import { ISwapRouter } from "../interfaces/ISwapRouter.sol";

/// @title PearStakingAirdrop
/// @notice Contract for staking PEAR tokens and earning rewards.
contract PearStakingAirdrop is ComptrollerManager, Initializable {
    struct Tier {
        address tierNFTContract;
        uint256 perNFTAllocation;
    }

    IPearStaker public stPearToken;
    IERC20 public pearToken;

    address public vault;

    address public goldNFT;
    address public silverNFT;
    address public bronzeNFT;

    uint256 public goldAllocationPerNFT;
    uint256 public silverAllocationPerNFT;
    uint256 public bronzeAllocationPerNFT;

    mapping(address => bool) public hasClaimed;

    event AirdropClaimed(address indexed user, uint256 amount);
    event AirdropWithdrawn(address indexed admin);

    /// @notice Modifier to restrict access to only the contract owner.
    modifier onlyAdmin() {
        if (comptroller.admin() != msg.sender) {
            revert Errors.Airdrop_NotComptrollerAdmin();
        }
        _;
    }

    constructor() {
        _disableInitializers();
    }

    function initialize(
        address _comptroller,
        address _stPearToken,
        address _pearToken,
        address _pearTokenValut,
        Tier memory _goldTier,
        Tier memory _silverTier,
        Tier memory _bronzeTier
    )
        external
        initializer
    {
        _comptrollerInit(_comptroller);
        stPearToken = IPearStaker(_stPearToken);
        pearToken = IERC20(_pearToken);
        vault = _pearTokenValut;
        goldNFT = _goldTier.tierNFTContract;
        silverNFT = _silverTier.tierNFTContract;
        bronzeNFT = _bronzeTier.tierNFTContract;

        goldAllocationPerNFT = _goldTier.perNFTAllocation;
        silverAllocationPerNFT = _silverTier.perNFTAllocation;
        bronzeAllocationPerNFT = _bronzeTier.perNFTAllocation;
    }

    /**
     * @dev Checks user's eligibility for airdrop
     * @param _user Address to check
     * @return Eligible amount of tokens
     */
    function checkEligibility(address _user) public view returns (uint256) {
        uint256 totalEligibleAmount = 0;

        if (IERC721(goldNFT).balanceOf(_user) > 0) {
            totalEligibleAmount +=
                goldAllocationPerNFT * IERC721(goldNFT).balanceOf(_user);
        }

        if (IERC721(silverNFT).balanceOf(_user) > 0) {
            totalEligibleAmount +=
                silverAllocationPerNFT * IERC721(silverNFT).balanceOf(_user);
        }

        if (IERC721(bronzeNFT).balanceOf(_user) > 0) {
            totalEligibleAmount +=
                bronzeAllocationPerNFT * IERC721(bronzeNFT).balanceOf(_user);
        }

        return totalEligibleAmount;
    }

    /**
     * @dev Claim tokens, mint stPEAR, and stake
     */
    function claim() external {
        if (hasClaimed[msg.sender]) {
            revert Errors.Airdrop_ALREADY_CLAIMED();
        }
        uint256 userAllocation = checkEligibility(msg.sender);
        if (userAllocation == 0) {
            revert Errors.Airdrop_NOT_ELIGIBLE();
        }
        hasClaimed[msg.sender] = true;

        // transfer PEAR tokens to this contract
        pearToken.transferFrom(vault, address(this), userAllocation);
        pearToken.approve(address(stPearToken), userAllocation);
        stPearToken.stakeFor(msg.sender, userAllocation);
        emit AirdropClaimed(msg.sender, userAllocation);
    }
}

// SPDX-License-Identifier: MIT
pragma solidity 0.8.20;

import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";

/// @title IPearBase
/// @notice Base logic for all Pear contracts.
interface IPearStaker is IERC20 {
    function initialize(address _pearToken, address _comptroller) external;
    function stake(uint256 amount) external;
    function stakeFor(address account, uint256 amount) external;
    function unstake(uint256 amount) external;
    function depositStakerFee() external payable;
    function earned(address account) external view returns (uint256, uint256);
    function getReward() external;
    function getStakingReward() external;
    function compoundStakingReward() external;
    function getExitFeeReward() external;

    function setUniswapData(address _uniswapRouter, uint24 _poolFee) external;
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.20;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);

    /**
     * @dev Returns the value of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the value of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves a `value` amount of tokens from the caller's account to `to`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address to, uint256 value) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets a `value` amount of tokens as the allowance of `spender` over the
     * caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 value) external returns (bool);

    /**
     * @dev Moves a `value` amount of tokens from `from` to `to` using the
     * allowance mechanism. `value` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(address from, address to, uint256 value) external returns (bool);
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/IERC721.sol)

pragma solidity ^0.8.20;

import {IERC165} from "../../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 address zero.
     *
     * 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);
}

File 5 of 15 : Errors.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.20;

library Errors {
    /*//////////////////////////////////////////////////////////////////////////
                                GMX FACTORY ERRORS
    //////////////////////////////////////////////////////////////////////////*/
    error GmxFactory_NotPlatformLogic();
    error GmxFactory_TransactionFailedOnTokenTransfer();
    error GmxFactory_InsufficientGmxExecutionFee();
    error GmxFactory_TokenNotAllowed();
    error GmxFactory_DifferentCollateralToken();
    error GmxFactory_IncorrectGrossFeeAmount();
    error GmxFactory_HigherSizeDelta();
    error GmxFactory_NotOwner();
    error GmxFactory_NotAdapterOwner();
    error GmxFactory_PositionNotOpened();
    error GmxFactory_TransferFailed();
    error GmxFactory_NotNftHandler();
    error GmxFactory_NotPositionRouter();
    error GmxFactory_NotAdapter();
    error GmxFactory_NotGmxPositionRouter();
    error GmxFactory_NotCallBackReceiver();
    error GmxFactory_NotEnoughFeeFunds();
    error GmxFactory_SameIndexToken();
    error GmxFactory_NotComptrollerAdmin();
    error GmxFactory_DifferentPath();
    error GmxFactory_EntityCannotBe0Address();
    error GmxFactory_NotProposedComptroller();
    error GmxFactory_PreviosOrderPending();
    error GmxFactory_NotPositionNFT();
    error GmxFactory_UnknownOrderKey();
    error GmxFactory_BeaconAlreadySet();

    /*//////////////////////////////////////////////////////////////////////////
                               VERTEX FACTORY ERRORS
    //////////////////////////////////////////////////////////////////////////*/

    error VertexFactory_NotPlatformLogic();
    error VertexFactory_TokenNotAllowed();
    error VertexFactory_NotComptrollerAdmin();
    error VertexFactory_NotProposedComptroller();
    error VertexFactory_EntityCannotBe0Address();
    error VertexFactory_WrongValueSent(
        uint256 valueSent, uint256 expectedFeeAmount
    );
    error VertexFactory_NotCallbackWallet();
    error VertexFactoryCallback_FailedToSendFundsToUser();
    error VertexFactoryCallback_FailedToSendFundsToCallbackWallet();

    /*//////////////////////////////////////////////////////////////////////////
                                PLATFORM LOGIC ERRORS
    //////////////////////////////////////////////////////////////////////////*/
    error PlatformLogic_Unavailable();
    error PlatformLogic_NotFactory();
    error PlatformLogic_WrongFeeAmount();
    error PlatformLogic_GivenZeroAddress();
    error PlatformLogic_ExceedsAllowance(uint256 feeAmount);
    error PlatformLogic_NotEnoughBalance();
    error PlatformLogic_AddressSetInComptrollerIsNotThisOne();
    error PlatformLogic_FeeAmountCannotBeNull();
    error PlatformLogic_NotComptrollerAdmin();
    error PlatformLogic_InvalidSigner();
    error PlatformLogic_CodeCreatorIsNotMsgSender();
    error PlatformLogic_RefereeNotMsgSender();
    error PlatformLogic_ComptrollerCannot0BeAddress();
    error PlatformLogic_TransactionFailed();
    error PlatformLogic_WrongValueSent(
        uint256 expectedFeeAmount, uint256 feeAmountSent
    );
    error PlatformLogic_ExceedingBps();
    error PlatformLogic_NotPositionNFT();

    /*//////////////////////////////////////////////////////////////////////////
                                  GXM ADAPTER ERRORS
    //////////////////////////////////////////////////////////////////////////*/
    error GmxAdapter_IncorrectFeeAmount();
    error GmxAdapter_WithdrawFailed();
    error GmxAdapter_Unauthorized();
    error GmxAdapter_CannotBeZeroAddress();
    error GmxAdapter_NotComptrollerAdmin();
    error GmxAdapter_NotAdapterOwner();
    error GmxAdapter_NotGmxFactory();
    error GmxAdapter_NotPositionNFT();

    /*//////////////////////////////////////////////////////////////////////////
                                COMPTROLLER ERRORS
    //////////////////////////////////////////////////////////////////////////*/
    error Comptroller_CallerNotAdmin();
    error Comptroller_AddressNotSet();
    error Comptroller_AdminCannotBe0Address();
    error Comptroller_UnauthorizedAccount(address unauthorizedUser);
    error Comptroller_AddressGivenIsZeroAddress();

    /*//////////////////////////////////////////////////////////////////////////
                                REWARDSCLAIMER ERRORS
    //////////////////////////////////////////////////////////////////////////*/
    error RewardsClaimer_NotOwner();
    error RewardsClaimer_NotPlatformLogic();
    error RewardsClaimer_UserHasNoRewardsToClaimOrHasExceededClaimingAmount();
    error RewardsClaimer_CannotClaimRewardsInTheSameBlock();
    error RewardsClaimer_CannotSendTo0Address();
    error RewardsClaimer_NotWhitelistedPlatform();
    error RewardsClaimer_ExceedsMaxClaimForPlatform();
    error RewardsClaimer_TransferFailed();

    /*//////////////////////////////////////////////////////////////////////////
                                 POSITIONNFT ERRORS
    //////////////////////////////////////////////////////////////////////////*/

    error PositionNFT_CallerIsNotNftHandler();
    error PositionNft_NotComptrollerAdmin();
    error PositionNFT_NotAdapterOwner();
    error PositionNFT_PositionNonExistantOrAlreadyClosed();
    error PositionNFT_PositionAlreadyMinted();
    error PositionNFT_NotNftOwner();
    error PositionNFT_PositionNotClosed();
    error PositionNFT_NotPositionOwner(address positionOwner);
    error PositionNFT_NotOwner();
    error PositionNFT_NotComptrollerAdmin();
    error PositionNFT_ComptrollerCannot0BeAddress();
    error PositionNFT_NotProposedComptroller();
    error PositionNFT_TokenNotAllowed();
    error PositonNFT_UserHasAPendingPosition();

    /*//////////////////////////////////////////////////////////////////////////
                                 PEARSTAKER ERRORS
    //////////////////////////////////////////////////////////////////////////*/
    error PearStaker_TransferFailed();
    error PearStaker_ExitFeeTransferFailed();
    error PearStaker_InsufficientBalance(uint256 balance, uint256 amount);
    error PearStaker_InsufficientStakeAmount(uint256 amount);
    error StakingRewards_NotPlatformLogic();
    error PearStaker_ZeroEarnedAmount();
    error PearStaker_StakesAreNotTransferable();
    error PearStaker_PearTokenAlreadyInitialized();
    error PearStaker_NotComptrollerAdmin();
    error StakingRewards_NotPlatformLogicOrComptrollerAdmin();

    /*//////////////////////////////////////////////////////////////////////////
                                 FEEREBATEMANAGER ERRORS
    //////////////////////////////////////////////////////////////////////////*/
    error FeeRebateManager_InvalidTier();
    error FeeRebateManager_InvalidRebateTier();
    error FeeRebateManager_InvalidDiscountTier();
    error FeeRebateManager_AlreadyClaimed();
    error FeeRebateManager_NoRebateAvailable();
    error FeeRebateManager_InsufficientFunds();
    error FeeRebateManager_NotComptrollerAdmin();
    error FeeRebateManager_NotFactory();
    error FeeRebateManager_NotPlatformLogic();
    error FeeRebateManager_TransferFailed();
    error FeeRebateManager_RebatesDisabled();
    error FeeRebateManager_CantClaimForCurrentMonth();

    error SymmFactory_NotComptrollerAdmin();
    error SymmFactory_NotBackendWallet();
    error SymmFactoryFailedToSendFundsToUser();
    error SymmFactoryNoClaimableDiscount();
    error SymmFactoryIncorrectAmountSent();
    error SymmFactoryNoAmountToDistribute();
    error SymmFactoryFailedToWithdrawUSDC();

    error PearVesting_NotAdmin();
    error PearVesting_ZeroAmount();
    error PearVesting_ZeroAddress();
    error PearVesting_InvalidEndTime();
    error PearVesting_InvalidCliffTime();
    error PearVesting_VestingNotRelease();
    error PearVesting_NotRecipient();
    error PearVesting_CliffNotReached();
    error PearVesting_NothingToClaim();
    error PearVesting_TransferFailed();
    error PearVesting_InvalidPlanId();
    error PearVesting_LowerAmount();
    error PearVesting_InvalidInputLength();

    error Airdrop_ALREADY_CLAIMED();
    error Airdrop_NOT_ELIGIBLE();
    error Airdrop_NotComptrollerAdmin();
}

File 6 of 15 : Events.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.20;

import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import { IPearBase } from "../interfaces/IPearBase.sol";
import { IPlatformLogic } from "../interfaces/IPlatformLogic.sol";
import { EventUtils } from "./EventUtils.sol";

library Events {
    event TokensWithdrawn(
        address indexed token, address indexed to, uint256 indexed amount
    );
    event EthWithdrawn(address indexed to, uint256 indexed amount);
    event PositionOpened(
        address indexed owner,
        address indexed adapter,
        bytes32 orderKey,
        bool isLong,
        bool isETHCollateral
    );
    event PositionClosed(
        address indexed owner,
        address indexed adapter,
        bytes32 orderKey,
        bool isLong
    );

    event PositionStatusSet(
        address indexed adapter, bool isLong, IPearBase.PositionStatus status
    );

    event CreateIncreasePosition(
        address indexed owner,
        address indexed adapter,
        uint256 amountIn,
        bytes32 orderKey,
        bool isLong,
        bool isETHCollateral
    );
    event CreateDecreasePosition(
        address indexed owner,
        address indexed adapter,
        uint256 amountOut,
        bytes32 orderKey,
        bool isLong
    );

    // orderKey
    event GmxCallback(
        address indexed adapter,
        bytes32 key,
        bool isExecuted,
        bool isIncrease,
        IPearBase.ExecutionState long,
        IPearBase.ExecutionState short
    );

    event ExecutionFeeRefunded(
        address indexed adapter, bytes32 key, uint256 amount
    );

    event PostionFailedTokenTransfer(
        address indexed refree,
        address indexed adapter,
        bool isLong,
        uint256 amount
    );

    event SplitBetweenStakersAndTreasuryFailed(
        address indexed refree,
        address indexed adapter,
        bool isLong,
        uint256 amount
    );

    event GmxOrderCallbackAtLiquidation(
        address indexed adapter, bytes32 key, bool isLong
    );

    event PlatformLogicsFactoryChanged(
        address indexed factory, bool indexed newState
    );

    event PlatformLogicChanged(
        IPlatformLogic oldAddress, IPlatformLogic newAddress
    );

    event ComptrollerChanged(address oldComptroller, address newComptroller);

    event AllowedTokenSet(IERC20 token, bool allowed);

    event EventLog(
        address msgSender,
        string indexed eventName,
        bytes32 indexed key,
        EventUtils.EventLogData eventData
    );

    ////////////////////////////////////////////////////
    ///////////// PearStaker events ////////////////////
    ////////////////////////////////////////////////////
    event Staked(address indexed user, uint256 amount);
    event Unstaked(address indexed user, uint256 amount, uint256 exitFee);
    event StakingReward(address indexed user, uint256 stakingRewards);
    event CompoundStakingReward(
        address indexed user,
        uint256 rewardsInEth,
        uint256 stakeAmount,
        uint256 exitFeeReward
    );
    event ExitFeeReward(address indexed user, uint256 exitFeeCollected);
    event DepositStakerFee(uint256 feeAmount, uint256 feeAmountEarnedPerToken);
    event FeeWithdrawn(uint256 amount);
    event TokenWithdrawn(uint256 amount);

    ////////////////////////////////////////////////////
    ///////////// FeeRebateManager events ////////////////////
    ////////////////////////////////////////////////////
    event RebateTierSet(
        uint256 tier, uint256 monthlyVolumeThreshold, uint256 rebatePercentage
    );
    event DiscountTierSet(
        uint256 tier, uint256 stakedAmountThreshold, uint256 discountPercentage
    );
    event Withdraw(uint256 amount);
    event RebateClaimed(address indexed user, uint256 monthId, uint256 rebate);
    event UpdateTradeDetails(address indexed user, uint256 volume, uint256 fee);
    event FeeRebateEnabledSet(bool isFeeRebateEnabled);
    event FeeRebateManagerNotUpdated();

    /// @notice Emitted when a new vesting plan is created
    /// @param planId The ID of the newly created vesting plan
    /// @param recipient The address of the recipient of the vested tokens
    /// @param amount The total amount of tokens to be vested
    /// @param start The timestamp when the vesting begins
    /// @param cliff The timestamp before which no tokens can be claimed
    /// @param end The timestamp when all tokens will be fully vested
    event VestingPlanCreated(
        uint256 indexed planId,
        address indexed recipient,
        uint256 amount,
        uint32 start,
        uint32 cliff,
        uint32 end
    );

    /// @notice Emitted when tokens are claimed from a vesting plan
    /// @param planId The ID of the vesting plan
    /// @param recipient The address of the recipient who claimed the tokens
    /// @param amount The amount of tokens claimed
    event VestingClaimed(
        uint256 indexed planId, address indexed recipient, uint256 amount
    );

    event VestingPlanUpdated(
        uint256 indexed planId, uint256 newAmount, uint32 newEnd
    );

    event VestingPlanCancelled(
        uint256 indexed planId,
        address indexed recipient,
        uint256 unclaimedAmount
    );

    event VestingRecipientChanged(uint256 indexed planId, address newRecipient);
}

// SPDX-License-Identifier: MIT
pragma solidity 0.8.20;

import { IComptroller } from "../interfaces/IComptroller.sol";

/**
 * @title Comptroller Manager
 * @dev This abstract contract provides mechanisms for managing a comptroller
 * reference within contracts.
 * It includes functionality to set and update the comptroller via a governance
 * process.
 * @notice This contract is intended to be inherited by other contracts
 * requiring control over comptroller functionalities.
 */
abstract contract ComptrollerManager {
    /// @notice The active comptroller contract
    IComptroller public comptroller;
    /// @notice The proposed new comptroller, pending acceptance
    address public proposedComptroller;

    /// @dev Error thrown when a zero address is provided where a valid address
    /// is required
    error ComptrollerManager_EntityCannotBe0Address();
    /// @dev Error thrown when an action is taken by an entity other than the
    /// comptroller admin
    error NotComptrollerAdmin();
    /// @dev Error thrown when an action is taken by an entity other than the
    /// proposed comptroller
    error NotProposedComptroller();

    /// @notice Emitted when the comptroller is changed
    event ComptrollerChanged(address oldComptroller, address newComptroller);

    /**
     * @dev Initializes the contract by setting the comptroller.
     * @param _comptroller The address of the comptroller.
     */
    function _comptrollerInit(address _comptroller) internal virtual {
        if (_comptroller == address(0)) {
            revert ComptrollerManager_EntityCannotBe0Address();
        }
        comptroller = IComptroller(_comptroller);
    }

    /**
     * @notice Proposes a new comptroller to be accepted by the new comptroller
     * itself.
     * @dev Sets a new proposed comptroller, which needs to accept its role to
     * be effective.
     * @param _comptroller The address of the proposed new comptroller.
     */
    function setComptroller(address _comptroller) external virtual {
        if (msg.sender != comptroller.admin()) {
            revert NotComptrollerAdmin();
        }

        if (_comptroller == address(0)) {
            revert ComptrollerManager_EntityCannotBe0Address();
        }
        proposedComptroller = _comptroller;
    }

    /**
     * @notice Accepts the role of comptroller, updating the contract's
     * comptroller reference.
     * @dev The proposed comptroller calls this function to accept the role,
     * triggering the ComptrollerChanged event.
     */
    function acceptComptroller() external virtual {
        if (msg.sender != proposedComptroller) {
            revert NotProposedComptroller();
        }
        emit ComptrollerChanged(address(comptroller), proposedComptroller);
        comptroller = IComptroller(proposedComptroller);
    }
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (proxy/utils/Initializable.sol)

pragma solidity ^0.8.20;

/**
 * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed
 * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an
 * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer
 * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.
 *
 * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be
 * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in
 * case an upgrade adds a module that needs to be initialized.
 *
 * For example:
 *
 * [.hljs-theme-light.nopadding]
 * ```solidity
 * contract MyToken is ERC20Upgradeable {
 *     function initialize() initializer public {
 *         __ERC20_init("MyToken", "MTK");
 *     }
 * }
 *
 * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {
 *     function initializeV2() reinitializer(2) public {
 *         __ERC20Permit_init("MyToken");
 *     }
 * }
 * ```
 *
 * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as
 * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.
 *
 * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure
 * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.
 *
 * [CAUTION]
 * ====
 * Avoid leaving a contract uninitialized.
 *
 * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation
 * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke
 * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:
 *
 * [.hljs-theme-light.nopadding]
 * ```
 * /// @custom:oz-upgrades-unsafe-allow constructor
 * constructor() {
 *     _disableInitializers();
 * }
 * ```
 * ====
 */
abstract contract Initializable {
    /**
     * @dev Storage of the initializable contract.
     *
     * It's implemented on a custom ERC-7201 namespace to reduce the risk of storage collisions
     * when using with upgradeable contracts.
     *
     * @custom:storage-location erc7201:openzeppelin.storage.Initializable
     */
    struct InitializableStorage {
        /**
         * @dev Indicates that the contract has been initialized.
         */
        uint64 _initialized;
        /**
         * @dev Indicates that the contract is in the process of being initialized.
         */
        bool _initializing;
    }

    // keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.Initializable")) - 1)) & ~bytes32(uint256(0xff))
    bytes32 private constant INITIALIZABLE_STORAGE = 0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00;

    /**
     * @dev The contract is already initialized.
     */
    error InvalidInitialization();

    /**
     * @dev The contract is not initializing.
     */
    error NotInitializing();

    /**
     * @dev Triggered when the contract has been initialized or reinitialized.
     */
    event Initialized(uint64 version);

    /**
     * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,
     * `onlyInitializing` functions can be used to initialize parent contracts.
     *
     * Similar to `reinitializer(1)`, except that in the context of a constructor an `initializer` may be invoked any
     * number of times. This behavior in the constructor can be useful during testing and is not expected to be used in
     * production.
     *
     * Emits an {Initialized} event.
     */
    modifier initializer() {
        // solhint-disable-next-line var-name-mixedcase
        InitializableStorage storage $ = _getInitializableStorage();

        // Cache values to avoid duplicated sloads
        bool isTopLevelCall = !$._initializing;
        uint64 initialized = $._initialized;

        // Allowed calls:
        // - initialSetup: the contract is not in the initializing state and no previous version was
        //                 initialized
        // - construction: the contract is initialized at version 1 (no reininitialization) and the
        //                 current contract is just being deployed
        bool initialSetup = initialized == 0 && isTopLevelCall;
        bool construction = initialized == 1 && address(this).code.length == 0;

        if (!initialSetup && !construction) {
            revert InvalidInitialization();
        }
        $._initialized = 1;
        if (isTopLevelCall) {
            $._initializing = true;
        }
        _;
        if (isTopLevelCall) {
            $._initializing = false;
            emit Initialized(1);
        }
    }

    /**
     * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the
     * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be
     * used to initialize parent contracts.
     *
     * A reinitializer may be used after the original initialization step. This is essential to configure modules that
     * are added through upgrades and that require initialization.
     *
     * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`
     * cannot be nested. If one is invoked in the context of another, execution will revert.
     *
     * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in
     * a contract, executing them in the right order is up to the developer or operator.
     *
     * WARNING: Setting the version to 2**64 - 1 will prevent any future reinitialization.
     *
     * Emits an {Initialized} event.
     */
    modifier reinitializer(uint64 version) {
        // solhint-disable-next-line var-name-mixedcase
        InitializableStorage storage $ = _getInitializableStorage();

        if ($._initializing || $._initialized >= version) {
            revert InvalidInitialization();
        }
        $._initialized = version;
        $._initializing = true;
        _;
        $._initializing = false;
        emit Initialized(version);
    }

    /**
     * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the
     * {initializer} and {reinitializer} modifiers, directly or indirectly.
     */
    modifier onlyInitializing() {
        _checkInitializing();
        _;
    }

    /**
     * @dev Reverts if the contract is not in an initializing state. See {onlyInitializing}.
     */
    function _checkInitializing() internal view virtual {
        if (!_isInitializing()) {
            revert NotInitializing();
        }
    }

    /**
     * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.
     * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized
     * to any version. It is recommended to use this to lock implementation contracts that are designed to be called
     * through proxies.
     *
     * Emits an {Initialized} event the first time it is successfully executed.
     */
    function _disableInitializers() internal virtual {
        // solhint-disable-next-line var-name-mixedcase
        InitializableStorage storage $ = _getInitializableStorage();

        if ($._initializing) {
            revert InvalidInitialization();
        }
        if ($._initialized != type(uint64).max) {
            $._initialized = type(uint64).max;
            emit Initialized(type(uint64).max);
        }
    }

    /**
     * @dev Returns the highest version that has been initialized. See {reinitializer}.
     */
    function _getInitializedVersion() internal view returns (uint64) {
        return _getInitializableStorage()._initialized;
    }

    /**
     * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.
     */
    function _isInitializing() internal view returns (bool) {
        return _getInitializableStorage()._initializing;
    }

    /**
     * @dev Returns a pointer to the storage namespace.
     */
    // solhint-disable-next-line var-name-mixedcase
    function _getInitializableStorage() private pure returns (InitializableStorage storage $) {
        assembly {
            $.slot := INITIALIZABLE_STORAGE
        }
    }
}

// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity >=0.7.5;
pragma abicoder v2;

/// @title Callback for IUniswapV3PoolActions#swap
/// @notice Any contract that calls IUniswapV3PoolActions#swap must implement
/// this interface
interface IUniswapV3SwapCallback {
    /// @notice Called to `msg.sender` after executing a swap via
    /// IUniswapV3Pool#swap.
    /// @dev In the implementation you must pay the pool tokens owed for the
    /// swap.
    /// The caller of this method must be checked to be a UniswapV3Pool deployed
    /// by the canonical UniswapV3Factory.
    /// amount0Delta and amount1Delta can both be 0 if no tokens were swapped.
    /// @param amount0Delta The amount of token0 that was sent (negative) or
    /// must be received (positive) by the pool by
    /// the end of the swap. If positive, the callback must send that amount of
    /// token0 to the pool.
    /// @param amount1Delta The amount of token1 that was sent (negative) or
    /// must be received (positive) by the pool by
    /// the end of the swap. If positive, the callback must send that amount of
    /// token1 to the pool.
    /// @param data Any data passed through by the caller via the
    /// IUniswapV3PoolActions#swap call
    function uniswapV3SwapCallback(
        int256 amount0Delta,
        int256 amount1Delta,
        bytes calldata data
    )
        external;
}

/// @title Router token swapping functionality
/// @notice Functions for swapping tokens via Uniswap V3
interface ISwapRouter is IUniswapV3SwapCallback {
    struct ExactInputSingleParams {
        address tokenIn;
        address tokenOut;
        uint24 fee;
        address recipient;
        uint256 deadline;
        uint256 amountIn;
        uint256 amountOutMinimum;
        uint160 sqrtPriceLimitX96;
    }

    function WETH9() external view returns (address);

    /// @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);

    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);

    struct ExactOutputSingleParams {
        address tokenIn;
        address tokenOut;
        uint24 fee;
        address recipient;
        uint256 deadline;
        uint256 amountOut;
        uint256 amountInMaximum;
        uint160 sqrtPriceLimitX96;
    }

    /// @notice Swaps as little as possible of one token for `amountOut` of
    /// another token
    /// @param params The parameters necessary for the swap, encoded as
    /// `ExactOutputSingleParams` in calldata
    /// @return amountIn The amount of the input token
    function exactOutputSingle(ExactOutputSingleParams calldata params)
        external
        payable
        returns (uint256 amountIn);

    struct ExactOutputParams {
        bytes path;
        address recipient;
        uint256 deadline;
        uint256 amountOut;
        uint256 amountInMaximum;
    }

    /// @notice Swaps as little as possible of one token for `amountOut` of
    /// another along the specified path (reversed)
    /// @param params The parameters necessary for the multi-hop swap, encoded
    /// as `ExactOutputParams` in calldata
    /// @return amountIn The amount of the input token
    function exactOutput(ExactOutputParams calldata params)
        external
        payable
        returns (uint256 amountIn);
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/IERC165.sol)

pragma solidity ^0.8.20;

/**
 * @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);
}

File 11 of 15 : IPearBase.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.20;

/// @title IPearBase Interface
/// @notice Basic interface for common functions across Pear-related contracts.
interface IPearBase {
    /// @notice Marks the different execution state of a position
    enum ExecutionState {
        Idle,
        Pending,
        Success,
        Failed
    }

    /// @notice Marks the status of a position
    enum PositionStatus {
        NotExecuted,
        Opened,
        Closed,
        Transferred,
        Liquidated
    }

    struct PositionData {
        bool isLong;
        address collateralToken;
        address marketAddress;
        bytes32 orderKey;
        ExecutionState orderExecutionState;
        bool isOrderMarketIncrease;
        PositionStatus positionStatus;
    }

    struct PairPositionData {
        PositionData long;
        PositionData short;
        uint256 timestamp;
    }

    struct CreateOrderArgs {
        address initialCollateralToken;
        address[] swapPath;
        address marketAddress;
        uint256 sizeDelta;
        uint256 initialCollateralDeltaAmount;
        uint256 minOut;
        uint256 executionFee;
        uint256 acceptablePrice;
        uint256 triggerPrice;
    }

    struct OpenPositionsArgs {
        CreateOrderArgs long;
        CreateOrderArgs short;
        uint256 totalAmountIn;
    }
}

File 12 of 15 : IPlatformLogic.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.20;

import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";

/// @title IPlatformLogic Interface
/// @notice Interface for defining the core logic and rules for trading
/// operations.
interface IPlatformLogic {
    /*//////////////////////////////////////////////////////////////////////////
                                EVENTS
    //////////////////////////////////////////////////////////////////////////*/

    event BackendVerifierChanged(
        address oldBackendVerifier, address newBackendVerifier
    );

    event ManagePositionFeeChanged(
        uint256 oldManagePositionFee, uint256 newManagePositionFee
    );
    event PlatformFeeChanged(uint256 oldPlatformFee, uint256 newPlatformFee);

    event MintFeeChanged(uint256 oldMintFee, uint256 newMintFee);

    event RefereeDiscountChanged(
        uint256 oldRefereeDiscount, uint256 newRefereeDiscount
    );

    event ReferrerFeeChanged(
        uint256 oldReferrerFeeChanged, uint256 newReferrerFeeChanged
    );

    event PearTreasuryChanged(address oldTreasury, address newTreasury);

    event PearStakingContractChanged(
        address oldPearStakingContract, address newPearStakingContract
    );

    event TreasuryFeeSplitChanged(
        uint256 oldTreasuryFee, uint256 newTreasuryFee
    );

    event ReferralCodeAdded(address indexed referrer, bytes32 code);

    event ReferralCodeEdited(
        address indexed referrer, bytes32 code, address admin
    );

    event Referred(
        address indexed referrer,
        address indexed referee,
        address indexed adapter,
        uint256 amount
    );

    event RefereeAdded(address indexed referee, bytes32 code);
    event RefereeEdited(address indexed referee, bytes32 code, address admin);

    event FactorySet(address factory, bool state);

    event PendingTokenWithdrawal(address referrer, uint256 amount);

    event PendingEthWithdrawal(address referrer, uint256 amount);

    event TokenWithdrawal(address withdrawer, uint256 amount);

    event EthWithdrawal(address withdrawer, uint256 amount);

    event FeesPaid(
        address indexed user,
        uint256 indexed feeAmount,
        uint256 indexed grossAmountAfterFee
    );

    event FeesPaidToStakingContract(
        address indexed stakingContract, uint256 indexed feeAmount
    );
    event FeesPaidToPearTreasury(
        address indexed pearTreasury, uint256 indexed feeAmount
    );

    event SetRefereeFeeAmount(
        address indexed positionHolder,
        address indexed adapterAddress,
        uint256 indexed feeAmount,
        bool isLong
    );

    event SetPendingReferrerFeeAmount(
        address adapter, address referrer, uint256 amount
    );

    event ArbRewardsFeeSplitChanged(
        uint256 oldArbRewardsFeeSplit, uint256 newArbRewardsFeeSplit
    );

    event PlatformLogic_AddedRewards(
        address indexed user, uint256 indexed amount
    );

    event FeesWithdrawn(uint256 amount);

    /*//////////////////////////////////////////////////////////////////////////
                                STRUCTS
    //////////////////////////////////////////////////////////////////////////*/

    struct ReferralCode {
        /// @notice address of the person wanting to create a referral code
        address referrer;
        /// @notice the bytes32 version of a referral code - converted by the
        /// backend
        bytes32 referralCode;
        /// @notice the EIP-712 signature of all other fields in the
        /// ReferralCode struct. For a referralCode to be valid, it must be
        /// signed by the backendVerifier
        bytes signature;
    }

    /*//////////////////////////////////////////////////////////////////////////
                                SETTERS
    //////////////////////////////////////////////////////////////////////////*/
    /// @notice Sets the arb rewards is active or not.
    function setGmxArbRewardActive(bool _isArbRewardActive) external;

    /// @notice Sets the arb rewards is active or not.
    function setVertexArbRewardActive(bool _isArbRewardActive) external;

    /// @notice Sets the arb rewards is active or not.
    function setSymmArbRewardActive(bool _isArbRewardActive) external;

    /// @notice Sets a new backend verifier address.
    /// @param _newBackendVerifier The new address to be used as the backend
    /// verifier.
    function setBackendVerifierAddress(address _newBackendVerifier) external;

    /// @notice Sets the discount percentage for referees.
    /// @param _refereeDiscount The new discount percentage for referees.
    function setRefereeDiscount(uint256 _refereeDiscount) external;

    /// @notice Sets the referral fee percentage.
    /// @param _referrerFee The new referral fee percentage.
    function setReferrerFee(uint256 _referrerFee) external;

    /// @notice Sets the platform fee percentage.
    /// @param _platformFee The new platform fee percentage.
    function setPlatformFee(uint256 _platformFee) external;

    /// @notice Sets the fee split percentage that goes to the treasury.
    /// @param _treasuryFeeSplit The new treasury fee split percentage.
    function setTreasuryFeeSplit(uint256 _treasuryFeeSplit) external;

    /// @notice Sets the fee split percentage that goes to arb for platforms
    /// rewards.
    function setGmxArbRewardsFeeSplit(uint256 _arbRewardsFeeSplit) external;

    /// @notice Sets the fee split percentage that goes to arb for platforms
    /// rewards.
    function setVertexArbRewardsFeeSplit(uint256 _arbRewardsFeeSplit)
        external;

    /// @notice Sets the fee split percentage that goes to arb for platforms
    /// rewards.
    function setSymmArbRewardsFeeSplit(uint256 _arbRewardsFeeSplit) external;

    /// @notice Sets a new Pear Treasury address.
    /// @param _newTreasury The new address for the Pear Treasury.
    function setPearTreasury(address payable _newTreasury) external;

    /// @notice Converts USDC amounts to ETH
    /// @param amount the usdc amount to be converted
    function convertFeeToEth(uint256 amount) external returns (uint256);

    /// @notice Sets a new Pear Staking Contract address.
    /// @param _newStakingContract The new address for the Pear Staking
    /// Contract.
    function setPearStakingContract(address payable _newStakingContract)
        external;

    /// @notice Adds or removes a factory address.
    /// @param _factory The factory address to be added or removed.
    /// @param _state The state to set for the factory address (true for add,
    /// false for remove).
    function setFactory(address _factory, bool _state) external;

    /// @notice Sets the mint fee for a specific functionality in the platform.
    /// @param _mintFee The new mint fee.
    function setMintPositionFee(uint256 _mintFee) external;

    /*//////////////////////////////////////////////////////////////////////////
                                EXTERNAL FUNCTIONS
    //////////////////////////////////////////////////////////////////////////*/

    /// @notice Creates a new referral code.
    /// @param _referralCode The referral code data to be created.
    /// @return A boolean indicating success of the operation.
    function createReferralCode(ReferralCode memory _referralCode)
        external
        returns (bool);

    /// @notice Associates a referee with a referral code.
    /// @param _referralCode The referral code to associate the referee with.
    /// @param _referee The address of the referee being associated.
    /// @return A boolean indicating success of the operation.
    function addReferee(
        bytes32 _referralCode,
        address _referee
    )
        external
        returns (bool);

    /// @notice Associates a referee with a referral code.
    /// @notice Can only be called by Gmx Factory
    /// @param _referralCode The referral code to associate the referee with.
    /// @param _referee The address of the referee being associated.
    /// @return A boolean indicating success of the operation.
    function addRefereeFromFactory(
        bytes32 _referralCode,
        address _referee
    )
        external
        returns (bool);

    /// @notice Edits the referral code of a referrer.
    /// @param _referrer The address of the referrer whose code is being edited.
    /// @param _referralCode The new referral code to be associated with the
    /// referrer.
    function editReferralCode(
        address _referrer,
        bytes32 _referralCode
    )
        external;

    function getPlatformFeeOfOrder(
        address referee,
        uint256 grossAmount
    )
        external
        view
        returns (uint256);

    /// @notice Applies platform fee logic for Ethereum Vertex.
    function applyPlatformFeeEthVertex(
        address _referee,
        uint256 _feeAmountAfterDiscountAndWithdrawal,
        uint256 _feeAmountAfterDiscount,
        uint256 _referrerWithdrawal,
        bool _isReferralProgramApplied
    )
        external
        payable;

    /// @notice Applies mint fee logic for ETH GMX.
    function applyMintFeeEthGmx(address _referee) external payable;

    /// @notice Applies platform fee logic for ETH GMX.
    /// @param adapter The address of the adapter contract for order
    /// @param _referee The address of the user being charged the fee.
    /// @param _grossAmount The total transaction amount before fees.
    /// @param _factory The address of the factory implementing the logic.
    /// @return feeAmount The amount of fee to be applied.
    /// @return referrerWithdrawal The amount of fee for referrer
    function applyPlatformFeeETHGmx(
        address adapter,
        address _referee,
        uint256 _grossAmount,
        address _factory
    )
        external
        returns (uint256 feeAmount, uint256 referrerWithdrawal);

    /// @notice Checks the amount of token fees pending withdrawal by a
    /// referrer.
    /// @param _referrer The address of the referrer.
    /// @return The amount of fees pending withdrawal.
    function checkPendingTokenWithdrawals(
        address _referrer,
        IERC20 _token
    )
        external
        view
        returns (uint256);

    /// @notice Allows a user to withdraw their accumulated token fees.
    /// @param _token The ERC20 token address for which the fees are withdrawn.
    function withdrawTokenFees(IERC20 _token) external;

    /// @notice Allows a user to withdraw their accumulated eth fees from
    /// referral logic.
    function withdrawEthFees() external;

    /// @notice Calculates fees based on the provided amount and basis points.
    /// @param _amount The amount on which the fee is to be calculated.
    /// @param _bps Basis points used to calculate the fee.
    /// @return The calculated fee amount.
    function calculateFees(
        uint256 _amount,
        uint256 _bps
    )
        external
        pure
        returns (uint256);

    /// @notice Edits the referral code of referred users.
    /// @param _referrer The address of the referrer whose referred users' code
    /// is being edited.
    /// @param _referralCode The new referral code to be associated with the
    /// referred users.
    function editReferredUsers(
        address _referrer,
        bytes32 _referralCode
    )
        external;

    /// @notice Splits fees between stakers and the treasure.
    /// @param _referee The address of the user involved in the transaction.
    /// @param _adapterAddress The address of the adapter involved in the
    /// transaction.
    /// @param _isLong isLong
    /// @param _amount The amount of fees to be split.
    function splitBetweenStakersAndTreasuryEth(
        address _referee,
        address _adapterAddress,
        bool _isLong,
        uint256 _amount
    )
        external;

    /// @notice Adds token fees for withdrawal by a referrer.
    /// @param _referrer The address of the referrer.
    /// @param _amount The amount of fees to be added for withdrawal.
    /// @param _token The ERC20 token address for which the fees are added.
    function addTokenFeesForWithdrawal(
        address _referrer,
        uint256 _amount,
        IERC20 _token
    )
        external;

    /// @notice function to calculate the platform fee for a given user on
    /// Vertex's side
    function calculatePlatformFeeEthVertex(
        address _referee,
        uint256 _grossAmount
    )
        external
        returns (
            uint256 _feeAmountAfterDiscountAndWithdrawal,
            uint256 _feeAmountAfterDiscount,
            uint256 _referrerWithdrawal,
            bool _isReferralProgramApplied
        );

    /// @notice Sets the fee amount for a referee.
    /// @param _referee The address of the referee.
    /// @param _adapterAddress The address of the adapter involved in the
    /// transaction.
    /// @param _isLong isLong
    /// @param _feeAmount The fee amount to be set.
    function setRefereeFeeAmount(
        address _referee,
        address _adapterAddress,
        bool _isLong,
        uint256 _feeAmount
    )
        external;

    /// @notice Handles token amount when a position fails.
    /// @param _referee The address of the user involved in the failed
    /// transaction.
    /// @param _adapterAddress The address of the adapter involved in the
    /// transaction.
    /// @param _isLong isLong
    /// @param _feeAmount The fee amount involved in the failed transaction.
    function handleTokenAmountWhenPositionHasFailed(
        address _referee,
        address _adapterAddress,
        bool _isLong,
        uint256 _feeAmount
    )
        external;

    function splitBetweenStakersAndTreasuryFromSymm() external payable;

    function applyPlatformFeeEthSymm(
        address _user,
        uint256 _feeAmount
    )
        external
        returns (uint256, uint256);

    /*//////////////////////////////////////////////////////////////////////////
                                VIEW FUNCTIONS
    //////////////////////////////////////////////////////////////////////////*/

    /// @notice View function to get the address used to sign and validate
    /// referral codes.
    function backendVerifier() external view returns (address);

    /// @notice View function to get the platform fee as a percentage of the
    /// margin size.
    function platformFee() external view returns (uint256);

    /// @notice View function to get the mint fee in USDC used in a specific
    /// function.
    function mintFeeInUsdc() external view returns (uint256);

    /// @notice View function to get the percentage of the platform fee
    /// allocated to referrers.
    function referrerFee() external view returns (uint256);

    /// @notice View function to get the discount percentage for referees off
    /// the platform fee.
    function refereeDiscount() external view returns (uint256);

    /// @notice View function to get the portion of fees sent to the Pear
    /// Treasury.
    function treasuryFeeSplit() external view returns (uint256);

    /// @notice View function to get the arb rewards is active or not.
    function isGmxArbRewardActive() external view returns (bool);

    /// @notice View function to get the arb rewards is active or not.
    function isVertexArbRewardActive() external view returns (bool);

    /// @notice View function to get the arb rewards is active or not.
    function isSymmArbRewardActive() external view returns (bool);

    /// @notice View function to get the % of ArbRewardsFeeSplit - e.g 7000 -
    /// 70%
    function gmxArbRewardsFeeSplit() external view returns (uint256);

    /// @notice View function to get the % of ArbRewardsFeeSplit - e.g 7000 -
    /// 70%
    function vertexArbRewardsFeeSplit() external view returns (uint256);

    /// @notice View function to get the % of ArbRewardsFeeSplit - e.g 7000 -
    /// 70%
    function symmArbRewardsFeeSplit() external view returns (uint256);

    /// @notice View function to get the address of the Pear Treasury.
    function PearTreasury() external view returns (address payable);

    /// @notice View function to get the address of the Pear Staking Contract.
    function PearStakingContract() external view returns (address payable);

    /// @notice Retrieves the owner of a specific referral code.
    /// @param _referralCode The referral code to check.
    /// @return codeOwner The address of the owner of the referral code.
    function viewReferralCodeOwner(bytes32 _referralCode)
        external
        view
        returns (address codeOwner);

    /// @notice Retrieves the referral code associated with a referrer.
    /// @param _referrer The address of the referrer.
    /// @return code The referral code associated with the referrer.
    function viewReferrersCode(address _referrer)
        external
        view
        returns (bytes32 code);

    /// @notice Retrieves the referral code used by a referred user.
    /// @param _referredUser The address of the referred user.
    /// @return code The referral code used by the referred user.
    function viewReferredUser(address _referredUser)
        external
        view
        returns (bytes32 code);

    /// @notice Retrieves the fee amount set for a referee.
    /// @param _referee The address of the referee.
    /// @param _adapterAddress The address of the adapter involved in the
    /// transaction.
    /// @param _isLong isLong
    /// @return The fee amount set for the referee.
    function viewRefereeFeeAmount(
        address _referee,
        address _adapterAddress,
        bool _isLong
    )
        external
        view
        returns (uint256);

    /// @notice Checks who referred a given user.
    /// @param _referredUser The address of the user being checked.
    /// @return referrer The address of the referrer.
    function checkReferredUser(address _referredUser)
        external
        view
        returns (address referrer);

    /// @notice Retrieves the current chain ID.
    /// @return The chain ID of the current blockchain.
    function getChainID() external view returns (uint256);
}

// SPDX-License-Identifier: BUSL-1.1

pragma solidity ^0.8.20;

library EventUtils {
  struct EmitPositionDecreaseParams {
    bytes32 key;
    address account;
    address market;
    address collateralToken;
    bool isLong;
  }

  struct EventLogData {
    AddressItems addressItems;
    UintItems uintItems;
    IntItems intItems;
    BoolItems boolItems;
    Bytes32Items bytes32Items;
    BytesItems bytesItems;
    StringItems stringItems;
  }

  struct AddressItems {
    AddressKeyValue[] items;
    AddressArrayKeyValue[] arrayItems;
  }

  struct UintItems {
    UintKeyValue[] items;
    UintArrayKeyValue[] arrayItems;
  }

  struct IntItems {
    IntKeyValue[] items;
    IntArrayKeyValue[] arrayItems;
  }

  struct BoolItems {
    BoolKeyValue[] items;
    BoolArrayKeyValue[] arrayItems;
  }

  struct Bytes32Items {
    Bytes32KeyValue[] items;
    Bytes32ArrayKeyValue[] arrayItems;
  }

  struct BytesItems {
    BytesKeyValue[] items;
    BytesArrayKeyValue[] arrayItems;
  }

  struct StringItems {
    StringKeyValue[] items;
    StringArrayKeyValue[] arrayItems;
  }

  struct AddressKeyValue {
    string key;
    address value;
  }

  struct AddressArrayKeyValue {
    string key;
    address[] value;
  }

  struct UintKeyValue {
    string key;
    uint256 value;
  }

  struct UintArrayKeyValue {
    string key;
    uint256[] value;
  }

  struct IntKeyValue {
    string key;
    int256 value;
  }

  struct IntArrayKeyValue {
    string key;
    int256[] value;
  }

  struct BoolKeyValue {
    string key;
    bool value;
  }

  struct BoolArrayKeyValue {
    string key;
    bool[] value;
  }

  struct Bytes32KeyValue {
    string key;
    bytes32 value;
  }

  struct Bytes32ArrayKeyValue {
    string key;
    bytes32[] value;
  }

  struct BytesKeyValue {
    string key;
    bytes value;
  }

  struct BytesArrayKeyValue {
    string key;
    bytes[] value;
  }

  struct StringKeyValue {
    string key;
    string value;
  }

  struct StringArrayKeyValue {
    string key;
    string[] value;
  }

  function initItems(AddressItems memory items, uint256 size) internal pure {
    items.items = new EventUtils.AddressKeyValue[](size);
  }

  function initArrayItems(AddressItems memory items, uint256 size) internal pure {
    items.arrayItems = new EventUtils.AddressArrayKeyValue[](size);
  }

  function setItem(
    AddressItems memory items,
    uint256 index,
    string memory key,
    address value
  ) internal pure {
    items.items[index].key = key;
    items.items[index].value = value;
  }

  function setItem(
    AddressItems memory items,
    uint256 index,
    string memory key,
    address[] memory value
  ) internal pure {
    items.arrayItems[index].key = key;
    items.arrayItems[index].value = value;
  }

  function initItems(UintItems memory items, uint256 size) internal pure {
    items.items = new EventUtils.UintKeyValue[](size);
  }

  function initArrayItems(UintItems memory items, uint256 size) internal pure {
    items.arrayItems = new EventUtils.UintArrayKeyValue[](size);
  }

  function setItem(
    UintItems memory items,
    uint256 index,
    string memory key,
    uint256 value
  ) internal pure {
    items.items[index].key = key;
    items.items[index].value = value;
  }

  function setItem(
    UintItems memory items,
    uint256 index,
    string memory key,
    uint256[] memory value
  ) internal pure {
    items.arrayItems[index].key = key;
    items.arrayItems[index].value = value;
  }

  function initItems(IntItems memory items, uint256 size) internal pure {
    items.items = new EventUtils.IntKeyValue[](size);
  }

  function initArrayItems(IntItems memory items, uint256 size) internal pure {
    items.arrayItems = new EventUtils.IntArrayKeyValue[](size);
  }

  function setItem(
    IntItems memory items,
    uint256 index,
    string memory key,
    int256 value
  ) internal pure {
    items.items[index].key = key;
    items.items[index].value = value;
  }

  function setItem(
    IntItems memory items,
    uint256 index,
    string memory key,
    int256[] memory value
  ) internal pure {
    items.arrayItems[index].key = key;
    items.arrayItems[index].value = value;
  }

  function initItems(BoolItems memory items, uint256 size) internal pure {
    items.items = new EventUtils.BoolKeyValue[](size);
  }

  function initArrayItems(BoolItems memory items, uint256 size) internal pure {
    items.arrayItems = new EventUtils.BoolArrayKeyValue[](size);
  }

  function setItem(
    BoolItems memory items,
    uint256 index,
    string memory key,
    bool value
  ) internal pure {
    items.items[index].key = key;
    items.items[index].value = value;
  }

  function setItem(
    BoolItems memory items,
    uint256 index,
    string memory key,
    bool[] memory value
  ) internal pure {
    items.arrayItems[index].key = key;
    items.arrayItems[index].value = value;
  }

  function initItems(Bytes32Items memory items, uint256 size) internal pure {
    items.items = new EventUtils.Bytes32KeyValue[](size);
  }

  function initArrayItems(Bytes32Items memory items, uint256 size) internal pure {
    items.arrayItems = new EventUtils.Bytes32ArrayKeyValue[](size);
  }

  function setItem(
    Bytes32Items memory items,
    uint256 index,
    string memory key,
    bytes32 value
  ) internal pure {
    items.items[index].key = key;
    items.items[index].value = value;
  }

  function setItem(
    Bytes32Items memory items,
    uint256 index,
    string memory key,
    bytes32[] memory value
  ) internal pure {
    items.arrayItems[index].key = key;
    items.arrayItems[index].value = value;
  }

  function initItems(BytesItems memory items, uint256 size) internal pure {
    items.items = new EventUtils.BytesKeyValue[](size);
  }

  function initArrayItems(BytesItems memory items, uint256 size) internal pure {
    items.arrayItems = new EventUtils.BytesArrayKeyValue[](size);
  }

  function setItem(
    BytesItems memory items,
    uint256 index,
    string memory key,
    bytes memory value
  ) internal pure {
    items.items[index].key = key;
    items.items[index].value = value;
  }

  function setItem(
    BytesItems memory items,
    uint256 index,
    string memory key,
    bytes[] memory value
  ) internal pure {
    items.arrayItems[index].key = key;
    items.arrayItems[index].value = value;
  }

  function initItems(StringItems memory items, uint256 size) internal pure {
    items.items = new EventUtils.StringKeyValue[](size);
  }

  function initArrayItems(StringItems memory items, uint256 size) internal pure {
    items.arrayItems = new EventUtils.StringArrayKeyValue[](size);
  }

  function setItem(
    StringItems memory items,
    uint256 index,
    string memory key,
    string memory value
  ) internal pure {
    items.items[index].key = key;
    items.items[index].value = value;
  }

  function setItem(
    StringItems memory items,
    uint256 index,
    string memory key,
    string[] memory value
  ) internal pure {
    items.arrayItems[index].key = key;
    items.arrayItems[index].value = value;
  }
}

File 14 of 15 : IComptroller.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.20;

import { IAcceptComptroller } from "./IAcceptComptroller.sol";
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";

/**
 * @title IComptroller
 * @dev Interface for the Comptroller, which handles various administrative
 * tasks across the platform.
 * This interface allows for management of tokens, addresses, and certain key
 * settings across the system.
 */
interface IComptroller {
    /*//////////////////////////////////////////////////////////////////////////
                                EVENTS
    //////////////////////////////////////////////////////////////////////////*/

    event ComptrollerTransferAdmin(address oldAdmin, address newAdmin);
    event ComptrollerAcceptNewAdmin(address oldAdmin, address newAdmin);
    event SetAllowedToken(IERC20 token, bool allowed);
    event SetGmxFactory(address oldAddress, address newAddress);
    event SetVertexFactory(address oldAddress, address newAddress);
    event SetCallBackReceiver(address oldAddress, address newAddress);
    event SetPlatformLogic(address oldAddress, address newAddress);
    event SetPositionNft(address oldAddress, address newAddress);
    event SetGmxReader(address oldAddress, address newAddress);
    event SetGmxVault(address oldAddress, address newAddress);
    event SetGmxRouter(address oldAddress, address newAddress);
    event SetGmxExchangeRouter(address oldAddress, address newAddress);
    event SetReferralCode(bytes32 oldReferralCode, bytes32 newReferralCode);
    event SetMaxCallbackgasLimit(uint256 oldLimit, uint256 newLimit);
    event SetEthUsdAggregator(address oldAddress, address newAddress);
    event SetArbRewardsClaimer(address oldAddress, address newAddress);
    event SetStPearToken(address oldAddress, address newAddress);
    event SetFeeRebateManager(address oldAddress, address newAddress);

    /*//////////////////////////////////////////////////////////////////////////
                            SETTER FUNCTIONS
    //////////////////////////////////////////////////////////////////////////*/

    /// @notice Transfers administrative control to a new admin.
    /// @param newAdmin The address to which the admin role will be transferred.
    function transferAdmin(address newAdmin) external;

    /// @notice Accepts the role of admin for the caller.
    function acceptAdmin() external;

    /// @notice Accepts a comptroller assignment to ensure continuity in
    /// dependent contracts.
    /// @param acceptControllerContract The contract address that needs to
    /// accept the comptroller change.
    function acceptComptroller(IAcceptComptroller acceptControllerContract)
        external;

    /// @notice Sets a unique referral code for identifying transactions
    /// originating from Pear's systems.
    /// @param code The new referral code to set.
    function setReferralCode(bytes32 code) external;

    /// @notice Assigns the callback receiver contract which handles
    /// post-transaction events.
    /// @param receiver The address of the new callback receiver contract.
    function setCallBackReceiver(address receiver) external;

    /// @notice Sets the address of the GMX Factory contract responsible for
    /// order management.
    /// @param factory The address of the GMX Factory contract.
    function setGmxFactory(address factory) external;

    /// @param factory The address of the Vertex Factory contract.
    function setVertexFactory(address factory) external;

    /// @notice Sets the address of the platform logic contract which contains
    /// core business logic.
    /// @param _platformLogic The address of the platform logic contract.
    function setPlatformLogic(address _platformLogic) external;

    /// @notice Sets the address of the Position NFT contract, managing NFTs
    /// that represent positions.
    /// @param _positionNft The new Position NFT address.
    function setPositionNft(address _positionNft) external;

    /// @notice Sets the address of the GMX Reader contract used for reading
    /// contract states and variables.
    /// @param _reader The new reader contract address.
    function setGmxReader(address _reader) external;

    /// @notice Sets the address of the GMX Vault, where assets are managed and
    /// stored.
    /// @param _vault The new vault address.
    function setGmxVault(address _vault) external;

    /// @notice Sets the address of the GMX Router, managing routing of
    /// transactions.
    /// @param _router The new router address.
    function setGmxRouter(address _router) external;

    /// @notice Sets the address of the GMX Exchange Router for handling
    /// exchange operations.
    /// @param _exchangeRouter The new exchange router address.
    function setGmxExchangeRouter(address _exchangeRouter) external;

    /// @notice Sets whether a token is allowed for payments and other
    /// transactions.
    /// @param tokenFeePaymentAddress The token address to set the allowance
    /// status.
    /// @param allowed The allowance status, true if allowed.
    function setAllowedToken(
        IERC20 tokenFeePaymentAddress,
        bool allowed
    )
        external;

    /// @notice Sets the maximum gas limit for callbacks to prevent excessive
    /// gas usage.
    /// @param _maxCallbackgasLimit The new maximum callback gas limit.
    function setMaxCallbackGasLimit(uint256 _maxCallbackgasLimit) external;

    /// @notice Sets the address for the ETH/USD price aggregator.
    /// @param _ethUsdAggregator The new ETH/USD aggregator address.
    function setEthUsdAggregator(address _ethUsdAggregator) external;

    /// @notice Sets the address for the Arbitrage Rewards Claimer.
    /// @param _arbRewardsClaimer The new Arbitrage Rewards Claimer address.
    function setArbRewardsClaimer(address _arbRewardsClaimer) external;

    function setStPearToken(address _stPearToken) external;

    function setFeeRebateManager(address _feeRebateManager) external;

    /*//////////////////////////////////////////////////////////////////////////
                                VIEW FUNCTIONS
    //////////////////////////////////////////////////////////////////////////*/

    /// @notice Returns the address of the current administrator.
    /// @return admin The administrator's address.
    function admin() external view returns (address);

    /// @notice Returns the current GMX referral code.
    /// @return The GMX referral code.
    function gmxReferralCode() external view returns (bytes32);

    /// @notice Checks if a token is allowed for transactions.
    /// @param token The token address to check.
    /// @return true if the token is allowed, false otherwise.
    function allowedTokens(IERC20 token) external view returns (bool);

    /// @notice Checks if a token is allowed as collateral.
    /// @param token The token address to check.
    /// @return true if the token is allowed as collateral, false otherwise.
    function allowedCollateralTokens(address token)
        external
        view
        returns (bool);

    /// @notice Returns the address of the GMX Exchange Router.
    /// @return The address of the exchange router.
    function getExchangeRouter() external view returns (address);

    /// @notice Returns the address of the GMX Vault.
    /// @return The address of the vault.
    function getVault() external view returns (address);

    /// @notice Returns the address of the GMX Router.
    /// @return The address of the router.
    function getRouter() external view returns (address);

    /// @notice Returns the address of the GMX Reader.
    /// @return The address of the reader.
    function getReader() external view returns (address);

    /// @notice Returns the address of the GMX Factory.
    /// @return The address of the factory.
    function getGmxFactory() external view returns (address);

    /// @notice Returns the address of the Vertex Factory.
    /// @return The address of the factory.
    function getVertexFactory() external view returns (address);

    /// @notice Returns the address of the GMX Callback Receiver.
    /// @return The address of the callback receiver.
    function getCallBackReceiver() external view returns (address);

    /// @notice Returns the address of the Platform Logic.
    /// @return The address of the platform logic.
    function getPlatformLogic() external view returns (address);

    /// @notice Returns the address of the Position NFT.
    /// @return The address of the position NFT.
    function getPositionNft() external view returns (address);

    /// @notice Returns the maximum callback gas limit.
    /// @return The maximum callback gas limit.
    function getMaxCallBackLimit() external view returns (uint256);

    /// @notice Returns the address of the data store.
    /// @return The address of the data store.
    function getDatastore() external view returns (address);

    /// @notice Returns the address of the ETH/USD price aggregator.
    /// @return The address of the ETH/USD price aggregator.
    function getEthUsdAggregator() external view returns (address);

    function getArbRewardsClaimer()
        external
        view
        returns (address arbRewardsClaimer);

    function getStPearToken() external view returns (address stPearToken);
    function getFeeRebateManager()
        external
        view
        returns (address feeRebateManager);
}

File 15 of 15 : IAcceptComptroller.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.20;

/**
 * @title IAcceptComptroller
 * @notice Interface is used to provide the addresses with a way to call the
 * acceptComptroller function
 * @notice The acceptComptroller function is implemented accross all
 * Comptroller complient contracts and is used as a two step ownership transfer
 */
interface IAcceptComptroller {
  function acceptComptroller() external;
}

Settings
{
  "remappings": [
    "@openzeppelin/=lib/openzeppelin-contracts/",
    "@openzeppelin-upgradeable/=lib/openzeppelin-contracts-upgradeable/",
    "forge-std/=lib/forge-std/src/",
    "@solady/=lib/solady/src/",
    "@soladytokens/=lib/solady/src/tokens/",
    "@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/",
    "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
    "ds-test/=lib/forge-std/lib/ds-test/src/",
    "erc4626-tests/=lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/",
    "openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/",
    "openzeppelin-contracts/=lib/openzeppelin-contracts/",
    "solady/=lib/solady/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 2000
  },
  "metadata": {
    "useLiteralContent": false,
    "bytecodeHash": "ipfs",
    "appendCBOR": true
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "evmVersion": "paris",
  "viaIR": false,
  "libraries": {}
}

Contract ABI

API
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"Airdrop_ALREADY_CLAIMED","type":"error"},{"inputs":[],"name":"Airdrop_NOT_ELIGIBLE","type":"error"},{"inputs":[],"name":"ComptrollerManager_EntityCannotBe0Address","type":"error"},{"inputs":[],"name":"InvalidInitialization","type":"error"},{"inputs":[],"name":"NotComptrollerAdmin","type":"error"},{"inputs":[],"name":"NotInitializing","type":"error"},{"inputs":[],"name":"NotProposedComptroller","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"AirdropClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"admin","type":"address"}],"name":"AirdropWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldComptroller","type":"address"},{"indexed":false,"internalType":"address","name":"newComptroller","type":"address"}],"name":"ComptrollerChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint64","name":"version","type":"uint64"}],"name":"Initialized","type":"event"},{"inputs":[],"name":"acceptComptroller","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"bronzeAllocationPerNFT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"bronzeNFT","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"checkEligibility","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"comptroller","outputs":[{"internalType":"contract IComptroller","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"goldAllocationPerNFT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"goldNFT","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"hasClaimed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_comptroller","type":"address"},{"internalType":"address","name":"_stPearToken","type":"address"},{"internalType":"address","name":"_pearToken","type":"address"},{"internalType":"address","name":"_pearTokenValut","type":"address"},{"components":[{"internalType":"address","name":"tierNFTContract","type":"address"},{"internalType":"uint256","name":"perNFTAllocation","type":"uint256"}],"internalType":"struct PearStakingAirdrop.Tier","name":"_goldTier","type":"tuple"},{"components":[{"internalType":"address","name":"tierNFTContract","type":"address"},{"internalType":"uint256","name":"perNFTAllocation","type":"uint256"}],"internalType":"struct PearStakingAirdrop.Tier","name":"_silverTier","type":"tuple"},{"components":[{"internalType":"address","name":"tierNFTContract","type":"address"},{"internalType":"uint256","name":"perNFTAllocation","type":"uint256"}],"internalType":"struct PearStakingAirdrop.Tier","name":"_bronzeTier","type":"tuple"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"pearToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"proposedComptroller","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_comptroller","type":"address"}],"name":"setComptroller","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"silverAllocationPerNFT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"silverNFT","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"stPearToken","outputs":[{"internalType":"contract IPearStaker","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"vault","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.