// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity 0.8.6;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
import "@openzeppelin/contracts/utils/structs/EnumerableMap.sol";
import "./../utils/IERC721Enhanced.sol";
struct Lock {
uint256 amount;
uint256 end;
}
/**
* @title IxsLocker
* @author solace.fi
* @notice Stake your [**SOLACE**](./../../SOLACE) to receive voting rights, [**SOLACE**](./../../SOLACE) rewards, and more.
*
* Locks are ERC721s and can be viewed with [`locks()`](#locks). Each lock has an `amount` of [**SOLACE**](./../../SOLACE) and an `end` timestamp and cannot be transferred or withdrawn from before it unlocks. Locks have a maximum duration of four years.
*
* Users can create locks via [`createLock()`](#createlock) or [`createLockSigned()`](#createlocksigned), deposit more [**SOLACE**](./../../SOLACE) into a lock via [`increaseAmount()`](#increaseamount) or [`increaseAmountSigned()`](#increaseamountsigned), extend a lock via [`extendLock()`](#extendlock), and withdraw via [`withdraw()`](#withdraw), [`withdrawInPart()`](#withdrawinpart), or [`withdrawMany()`](#withdrawmany).
*
* Users and contracts (eg BondTellers) may deposit on behalf of another user or contract.
*
* Any time a lock is updated it will notify the listener contracts (eg StakingRewards).
*
* Note that transferring [**SOLACE**](./../../SOLACE) to this contract will not give you any rewards. You should deposit your [**SOLACE**](./../../SOLACE) via [`createLock()`](#createlock) or [`createLockSigned()`](#createlocksigned).
*/
interface IxsLocker is IERC721Enhanced {
/***************************************
EVENTS
***************************************/
/// @notice Emitted when a lock is created.
event LockCreated(uint256 xsLockID);
/// @notice Emitted when a lock is updated.
event LockUpdated(uint256 xsLockID, uint256 amount, uint256 end);
/// @notice Emitted when a lock is withdrawn from.
event Withdrawl(uint256 xsLockID, uint256 amount);
/// @notice Emitted when a listener is added.
event xsLockListenerAdded(address listener);
/// @notice Emitted when a listener is removed.
event xsLockListenerRemoved(address listener);
/***************************************
GLOBAL VARIABLES
***************************************/
/// @notice [**SOLACE**](./../../SOLACE) token.
function solace() external view returns (address);
/// @notice The maximum time into the future that a lock can expire.
function MAX_LOCK_DURATION() external view returns (uint256);
/// @notice The total number of locks that have been created.
function totalNumLocks() external view returns (uint256);
/***************************************
VIEW FUNCTIONS
***************************************/
/**
* @notice Information about a lock.
* @param xsLockID The ID of the lock to query.
* @return lock_ Information about the lock.
*/
function locks(uint256 xsLockID) external view returns (Lock memory lock_);
/**
* @notice Determines if the lock is locked.
* @param xsLockID The ID of the lock to query.
* @return locked True if the lock is locked, false if unlocked.
*/
function isLocked(uint256 xsLockID) external view returns (bool locked);
/**
* @notice Determines the time left until the lock unlocks.
* @param xsLockID The ID of the lock to query.
* @return time The time left in seconds, 0 if unlocked.
*/
function timeLeft(uint256 xsLockID) external view returns (uint256 time);
/**
* @notice Returns the amount of [**SOLACE**](./../../SOLACE) the user has staked.
* @param account The account to query.
* @return balance The user's balance.
*/
function stakedBalance(address account) external view returns (uint256 balance);
/**
* @notice The list of contracts that are listening to lock updates.
* @return listeners_ The list as an array.
*/
function getXsLockListeners() external view returns (address[] memory listeners_);
/***************************************
MUTATOR FUNCTIONS
***************************************/
/**
* @notice Deposit [**SOLACE**](./../../SOLACE) to create a new lock.
* @dev [**SOLACE**](./../../SOLACE) is transferred from msg.sender, assumes its already approved.
* @dev use end=0 to initialize as unlocked.
* @param recipient The account that will receive the lock.
* @param amount The amount of [**SOLACE**](./../../SOLACE) to deposit.
* @param end The timestamp the lock will unlock.
* @return xsLockID The ID of the newly created lock.
*/
function createLock(address recipient, uint256 amount, uint256 end) external returns (uint256 xsLockID);
/**
* @notice Deposit [**SOLACE**](./../../SOLACE) to create a new lock.
* @dev [**SOLACE**](./../../SOLACE) is transferred from msg.sender using ERC20Permit.
* @dev use end=0 to initialize as unlocked.
* @dev recipient = msg.sender
* @param amount The amount of [**SOLACE**](./../../SOLACE) to deposit.
* @param end The timestamp the lock will unlock.
* @param deadline Time the transaction must go through before.
* @param v secp256k1 signature
* @param r secp256k1 signature
* @param s secp256k1 signature
* @return xsLockID The ID of the newly created lock.
*/
function createLockSigned(uint256 amount, uint256 end, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external returns (uint256 xsLockID);
/**
* @notice Deposit [**SOLACE**](./../../SOLACE) to increase the value of an existing lock.
* @dev [**SOLACE**](./../../SOLACE) is transferred from msg.sender, assumes its already approved.
* @param xsLockID The ID of the lock to update.
* @param amount The amount of [**SOLACE**](./../../SOLACE) to deposit.
*/
function increaseAmount(uint256 xsLockID, uint256 amount) external;
/**
* @notice Deposit [**SOLACE**](./../../SOLACE) to increase the value of an existing lock.
* @dev [**SOLACE**](./../../SOLACE) is transferred from msg.sender using ERC20Permit.
* @param xsLockID The ID of the lock to update.
* @param amount The amount of [**SOLACE**](./../../SOLACE) to deposit.
* @param deadline Time the transaction must go through before.
* @param v secp256k1 signature
* @param r secp256k1 signature
* @param s secp256k1 signature
*/
function increaseAmountSigned(uint256 xsLockID, uint256 amount, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external;
/**
* @notice Extend a lock's duration.
* @dev Can only be called by the lock owner or approved.
* @param xsLockID The ID of the lock to update.
* @param end The new time for the lock to unlock.
*/
function extendLock(uint256 xsLockID, uint256 end) external;
/**
* @notice Withdraw from a lock in full.
* @dev Can only be called by the lock owner or approved.
* @dev Can only be called if unlocked.
* @param xsLockID The ID of the lock to withdraw from.
* @param recipient The user to receive the lock's [**SOLACE**](./../../SOLACE).
*/
function withdraw(uint256 xsLockID, address recipient) external;
/**
* @notice Withdraw from a lock in part.
* @dev Can only be called by the lock owner or approved.
* @dev Can only be called if unlocked.
* @param xsLockID The ID of the lock to withdraw from.
* @param recipient The user to receive the lock's [**SOLACE**](./../../SOLACE).
* @param amount The amount of [**SOLACE**](./../../SOLACE) to withdraw.
*/
function withdrawInPart(uint256 xsLockID, address recipient, uint256 amount) external;
/**
* @notice Withdraw from multiple locks in full.
* @dev Can only be called by the lock owner or approved.
* @dev Can only be called if unlocked.
* @param xsLockIDs The ID of the locks to withdraw from.
* @param recipient The user to receive the lock's [**SOLACE**](./../../SOLACE).
*/
function withdrawMany(uint256[] calldata xsLockIDs, address recipient) external;
/***************************************
GOVERNANCE FUNCTIONS
***************************************/
/**
* @notice Adds a listener.
* Can only be called by the current [**governor**](/docs/protocol/governance).
* @param listener The listener to add.
*/
function addXsLockListener(address listener) external;
/**
* @notice Removes a listener.
* Can only be called by the current [**governor**](/docs/protocol/governance).
* @param listener The listener to remove.
*/
function removeXsLockListener(address listener) external;
/**
* @notice Sets the base URI for computing `tokenURI`.
* Can only be called by the current [**governor**](/docs/protocol/governance).
* @param baseURI_ The new base URI.
*/
function setBaseURI(string memory baseURI_) external;
}
|