interface IUniversalVaultV2 {
    /* user events */

    event Locked(address delegate, address token, uint256 amount);
    event Unlocked(address delegate, address token, uint256 amount);
    event LockedERC721(address delegate, address token, uint256 tokenId);
    event UnlockedERC721(address delegate, address token, uint256 tokenId);
    event RageQuit(address delegate, address token, bool notified, string reason);
    event ERC721Received(address operator, address from, uint256 tokenId, bytes data);

    /* data types */

    struct LockData {
        address delegate;
        address token;
        uint256 balance;
    }

    /* initialize function */

    function initialize() external;

    /* user functions */

    function lock(
        address token,
        uint256 amount,
        bytes calldata permission
    ) external;

    function unlock(
        address token,
        uint256 amount,
        bytes calldata permission
    ) external;

    function lockERC721(
        address token,
        uint256 tokenId,
        bytes calldata permission
    ) external;

    function unlockERC721(
        address token,
        uint256 tokenId,
        bytes calldata permission
    ) external;

    function rageQuit(address delegate, address token)
        external
        returns (bool notified, string memory error);

    function transferERC20(
        address token,
        address to,
        uint256 amount
    ) external;

    function transferERC721(
        address token,
        address to,
        uint256 tokenId
    ) external;

    function transferETH(address to, uint256 amount) external payable;

    /* pure functions */

    function calculateLockID(address delegate, address token)
        external
        pure
        returns (bytes32 lockID);

    /* getter functions */

    function getPermissionHash(
        bytes32 eip712TypeHash,
        address delegate,
        address token,
        uint256 amount,
        uint256 nonce
    ) external view returns (bytes32 permissionHash);

    function getPermissionHashERC721(
        bytes32 eip712TypeHash,
        address delegate,
        address token,
        uint256 tokenId,
        uint256 nonce
    ) external view returns (bytes32 permissionHash);

    function getNonce() external view returns (uint256 nonce);

    function owner() external view returns (address ownerAddress);

    function getLockSetCount() external view returns (uint256 count);

    function getLockAt(uint256 index) external view returns (LockData memory lockData);

    function getBalanceDelegated(address token, address delegate)
        external
        view
        returns (uint256 balance);

    function getBalanceLocked(address token) external view returns (uint256 balance);

    function getNumERC721TypesLocked() external view returns (uint256 count);

    function getERC721TypeLockedAt(uint index) external view returns (address token);

    function getERC721LockedBalance(address token) external view returns (uint256 balance);

    function getERC721LockedAt(address token, uint index) external view returns (uint256 tokenId);

    function getNumERC721TypesInVault() external view returns (uint256 count);

    function getERC721TypeInVaultAt(uint index) external view returns (address token);

    function getERC721VaultBalance(address token) external view returns (uint256 balance);

    function getERC721InVaultAt(address token, uint index) external view returns (uint256 tokenId);

    function checkERC20Balances() external view returns (bool validity);

    function checkERC721Balances() external view returns (bool validity);
}
function calculateLockID(address delegate, address token)
    external
    pure
    returns (bytes32 lockID);

/* pure functions */