// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.0; /** * @title SOMA SomaEarn Contract. * @author SOMA.finance * @notice A fund raising contract for bootstrapping DEX liquidity pools. */ interface ISomaEarn { /** * @notice Returns the SomaEarn Token template address. */ function SOMA_EARN_TOKEN() external pure returns (address); /** * @notice Emitted when the {DelegationConfig} is updated. * @param prevConfig The previous delegation configuration. * @param newConfig The new delegation configuration. * @param sender The message sender that triggered the event. */ event DelegationConfigUpdated(DelegationConfig prevConfig, DelegationConfig newConfig, address indexed sender); /** * @notice Emitted when the {withdrawTo} address is updated. * @param prevTo The previous withdraw to address. * @param newTo The new withdraw to address. * @param sender The message sender that triggered the event. */ event WithdrawToUpdated(address prevTo, address newTo, address indexed sender); /** * @notice Emitted when a delegation is added to a pool. * @param poolId The pool ID. * @param amount The delegation amount denominated in the delegation asset. * @param sender The message sender that triggered the event. */ event DelegationAdded(bytes32 indexed poolId, uint256 amount, address indexed sender); /** * @notice Emitted when someone calls {moveDelegation}, transferring their delegation to a different pool. * @param fromPoolId The pool ID of the source pool. * @param toPoolId The pool ID of the destination pool. * @param amount The amount of the delegation asset to move. * @param sender TThe message sender that triggered the event. */ event DelegationMoved(bytes32 indexed fromPoolId, bytes32 indexed toPoolId, uint256 amount, address indexed sender); /** * @notice Emitted when the {DateConfig} is updated. * @param prevStartDate The previous unix timestamp for the start date. * @param prevEndDate The previous unix timestamp for the start date. * @param newStartDate The new unix timestamp for the end date. * @param newEndDate The new unix timestamp for the end date. * @param sender The message sender that triggered the event. */ event DatesUpdated( uint48 prevStartDate, uint48 prevEndDate, uint48 newStartDate, uint48 newEndDate, address indexed sender ); /** * @notice Emitted when the {Pool} is updated. * @param poolId The pool ID. * @param maxUserDelegation The max value a user can delegate. * @param maxTotalDelegation The max value that can be delegated to a pool. * @param requiredPrivileges The new required privileges. * @param enabled Boolean indicating if the pool is enabled. * @param sender The message sender that triggered the event. */ event PoolUpdated( bytes32 indexed poolId, uint256 maxUserDelegation, uint256 maxTotalDelegation, bytes32 requiredPrivileges, bool enabled, address indexed sender ); /** * @notice Emitted when the {Pool} is updated. * @param poolId The pool ID. * @param token The Token that belongs to the poolId */ event TokenCreated(bytes32 indexed poolId, address indexed token); /** * @notice Pool structure. Each pool will bootstrap liquidity for an upcoming DEX pair. * E.g: sTSLA/USDC * @param enabled Boolean indicating if the pool is enabled. * @param requiredPrivileges The required privileges of the pool. * @param maxUserDelegation The max amount a user can delegate. * @param maxTotalDelegation The max amount that can be delegated to this pool. */ struct Pool { bool enabled; uint256 maxUserDelegation; uint256 maxTotalDelegation; mapping(address => uint256) userDelegation; } /** * @notice Delegation Configuration structure. Each user will specify their own Delegation Configuration. * @param percentLocked The percentage of user rewards to delegate to phase2. * @param lockDuration The lock duration of the user rewards. */ struct DelegationConfig { uint8 percentLocked; uint8 lockDuration; } /** * @notice Returns the SomaEarn Global Admin Role. * @dev Equivalent to keccak256('SomaEarn.GLOBAL_ADMIN_ROLE'). */ function GLOBAL_ADMIN_ROLE() external pure returns (bytes32); /** * @notice Returns the SomaEarn Local Admin Role. */ function LOCAL_ADMIN_ROLE() external view returns (bytes32); /** * @notice Returns the ID of the SomaEarn. */ function id() external view returns (uint256); /** * @notice The address of the SomaEarn's delegation asset. */ function asset() external view returns (address); /** * @notice The date configuration of the SomaEarn. */ function startDate() external view returns (uint48); /** * @notice The date configuration of the SomaEarn. */ function endDate() external view returns (uint48); /** * @notice The address where the delegated funds will be withdrawn to. */ function withdrawTo() external view returns (address); /** * @notice Initialize function for the SomaEarn contract. * @param _id The ID of the SomaEarn. * @param _asset The address of the delegation asset for the pool. * @param _withdrawTo The withdrawTo address for the pool. * @param _startDate The start date configuration for the SomaEarn. * @param _endDate The end date configuration for the SomaEarn. */ function initialize(uint256 _id, address _asset, address _withdrawTo, uint48 _startDate, uint48 _endDate) external; /** * @notice Updates the SomaEarn's date configuration. * @param newStartDate The updated start date configuration. * @param newEndDate The updated end date configuration. * @custom:emits DatesUpdated * @custom:requirement The function caller must have the GLOBAL_ADMIN_ROLE or LOCAL_ADMIN_ROLE. */ function updateDateConfig(uint48 newStartDate, uint48 newEndDate) external; /** * @notice Sets the `withdrawTo` address. * @param account The updated `withdrawTo` address. * @custom:emits WithdrawToUpdated * @custom:requirement The function caller must have the GLOBAL_ADMIN_ROLE or LOCAL_ADMIN_ROLE. */ function setWithdrawTo(address account) external; /** * @notice Returns the delegation balance of an account, given a pool ID. * @param poolId The poolId to return the account's balance of. * @param account The account to return the balance of. * @return The delegation balance of `account` for the `poolId` pool. */ function balanceOf(bytes32 poolId, address account) external view returns (uint256); /** * @notice Returns the delegation sum of an account, given a pool ID. * @param poolId The poolId to return the account's sum of. * @param account The account to return the sum of. * @return The delegation sum of `account` for the `poolId` pool. */ function userDelegation(bytes32 poolId, address account) external view returns (uint256); /** * @notice Returns the ID of the SomaEarn. * @param poolId The poolId to return the token of. * @return The token address of the pool */ function token(bytes32 poolId) external view returns (address); /** * @notice Returns the delegation configuration of an account. * @param account The account to return the delegation configuration of. * @return The delegation configuration of the SomaEarn. */ function delegationConfig(address account) external view returns (DelegationConfig memory); /** * @notice Returns a boolean indicating if a pool is enabled. * @param poolId The pool ID to check the enabled status of. * @return True if the pool is enabled, False if the pool is disabled. */ function enabled(bytes32 poolId) external view returns (bool); /** * @notice Returns the required privileges of the pool. These privileges are required in order to * delegate. * @param poolId The pool ID to check the enabled status of. * @return The required privileges of the pool. */ function requiredPrivileges(bytes32 poolId) external view returns (bytes32); /** * @notice Returns the maximum delegation that a user can delegate to the pool. * @param poolId The pool ID to check the enabled status of. * @return The max user delegation of the specified pool. */ function maxUserDelegation(bytes32 poolId) external view returns (uint256); /** * @notice Returns the maximum amount that can be delegated to a specific pool. * @param poolId The pool ID to check the enabled status of. * @return The max total delegation of the specified pool */ function maxTotalDelegation(bytes32 poolId) external view returns (uint256); /** * @notice Updates the SomaEarn pool parameters. * @param poolId The pool ID. * @param maxUserDelegation The max value a user can delegate. * @param maxTotalDelegation The max value that can be delegated to a pool. * @param requiredPrivileges The new required privileges. * @param enabled Boolean indicating if the pool is enabled. * @custom:emits PoolUpdated * @custom:requirement The function caller must have the GLOBAL_ADMIN_ROLE or LOCAL_ADMIN_ROLE. * @custom:requirement The pool.maxUserDelegation must be less than or equal to pool.maxTotalDelegation */ function updatePool( bytes32 poolId, uint256 maxUserDelegation, uint256 maxTotalDelegation, bytes32 requiredPrivileges, bool enabled ) external; /** * @notice Withdraws tokens from the SomaEarn contract to the `withdrawTo` address. * @param amount The amount of tokens to be withdrawn. * @custom:requirement The function caller must have the GLOBAL_ADMIN_ROLE or LOCAL_ADMIN_ROLE. */ function withdraw(uint256 amount) external; /** * @notice Moves the accounts' delegated tokens from one pool to another. * @param fromPoolId The ID of the pool that the delegation will be moved from. * @param toPoolId The ID of the pool that the delegation will be moved to. * @param amount The amount of tokens to be moved. * @custom:emits DelegationMoved * @custom:requirement `fromPoolId` must not be equal to `toPoolId`. * @custom:requirement The SomaEarn's `phase1` must have started already. * @custom:requirement The SomaEarn's `phase2` must not have ended yet. * @custom:requirement `amount` must be greater than zero. * @custom:requirement The `fromPoolId` pool must be enabled. * @custom:requirement The `toPoolId` pool must be enabled. * @custom:requirement The delegation balance of the caller for the `fromPoolId` pool must be greater than * or equal to `amount`. * @custom:requirement The function caller must have the required privileges of the `fromPoolId` pool. * @custom:requirement The function caller must have the required privileges of the `toPoolId` pool. * @custom:requirement The total supply of the receiving pool's token must be less than or equal to the receiving pool's `maxTotalDelegation`. * @custom:requirement The function caller's receiving pool token balance must be less than or equal to the receiving pool's `maxUserDelegation`. * @custom:requirement The contracts must no be paused. */ function moveDelegation(bytes32 fromPoolId, bytes32 toPoolId, uint256 amount) external; /** * @notice Delegates tokens to the a specific pool. * @param poolId The ID of the pool to receive the delegation. * @param amount The amount of tokens to be delegated. * @custom:emits DelegationAdded * @custom:requirement `amount` must be greater than zero. * @custom:requirement The `poolId` pool must be enabled. * @custom:requirement The `poolId` pool's phase1 must have started already. * @custom:requirement The `poolId` pool's phase2 must not have ended yet. * @custom:requirement The function caller must have the `poolId` pool's required privileges. * @custom:requirement The total supply of the pool's token must be less than or equal to the pool's `maxTotalDelegation`. * @custom:requirement The function caller's pool token balance must be less than or equal to the pool's `maxUserDelegation`. * @custom:requirement The contracts must no be paused. */ function delegate(bytes32 poolId, uint256 amount) external; /** * @notice Updates the delegation configuration of an account. * @param newConfig The updated delegation configuration of the account. * @custom:emits DelegationConfigUpdated * @custom:requirement The ``newConfig``'s percent locked must be a valid percentage. * @custom:requirement The SomaEarn's phase1 must have started already. * @custom:requirement Given the SomaEarn's phase2 has ended, ``newConfig``'s percent locked must be * greater than the existing percent locked for the account. * @custom:requirement Given the SomaEarn's phase2 has ended, ``newConfig``'s lock duration must be equal * to the existing lock duration for the account. * @custom:requirement The contracts must no be paused. */ function updateDelegationConfig(DelegationConfig calldata newConfig) external; }