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

interface IStaking {
    error ExternalDepositsLocked();
    error ExternalClaimsLocked();
    error InsufficientBalance();
    error NotGatekeeper();

    event Staked(
        address sender,
        address receiver,
        uint256 amount,
        bool isRebase,
        bool isClaim
    );

    event Unstaked(
        address sender,
        address receiver,
        uint256 amount,
        bool isTrigger,
        bool isRebase
    );

    event DistributorSet(address distributor);
    event GatekeeperSet(address gatekeeper);
    event WarmupSet(uint256 warmup);

    struct Epoch {
        uint48 length;
        uint48 number;
        uint48 end;
        uint256 distribute;
    }

    struct Claim {
        uint256 deposit;
        uint256 shares;
        uint48 expiry;
        bool lock;
    }

    function stake(
        uint256 _amount,
        address _to,
        bool _isRebase,
        bool _isClaim
    ) external returns (uint256);

    function claim(address _recipient, bool _rebasing) external returns (uint256);
    function claimByAmount(
        address _recipient,
        uint256 _amount,
        bool _rebasing
    ) external returns (uint256);
    function breakout(bytes32 _receiver, uint256 _amount) external returns (uint256);
    function forfeit() external returns (uint256);
    function toggleLock() external;

    function unstake(
        uint256 _amount,
        address _to,
        bool _isTrigger,
        bool _isRebase
    ) external returns (uint256);

    function wrap(address _to, uint256 _amount) external returns (uint256 gBalance_);
    function unwrap(address _to, uint256 _amount) external returns (uint256 sBalance_);
    function ghost(bytes32 receiver, uint256 amount) external;
    function materialize(address receiver, uint256 amount) external;
    function rebase() external returns (uint256);

    function index() external view returns (uint256);
    function supplyInWarmup() external view returns (uint256);
    function ghostedSupply() external view returns (uint256);
    function totalReserves() external view returns (uint256);
    function baseSupply() external view returns (uint256);
}
