169 lines
8.1 KiB
Solidity
169 lines
8.1 KiB
Solidity
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
// This program is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
pragma solidity >=0.7.0 <0.9.0;
|
|
pragma experimental ABIEncoderV2;
|
|
|
|
import "../solidity-utils/openzeppelin/IERC20.sol";
|
|
|
|
import "./IVotingEscrow.sol";
|
|
|
|
/**
|
|
* @title Fee Distributor
|
|
* @notice Distributes any tokens transferred to the contract (e.g. Protocol fees and any BAL emissions) among veBAL
|
|
* holders proportionally based on a snapshot of the week at which the tokens are sent to the FeeDistributor contract.
|
|
* @dev Supports distributing arbitrarily many different tokens. In order to start distributing a new token to veBAL
|
|
* holders simply transfer the tokens to the `FeeDistributor` contract and then call `checkpointToken`.
|
|
*/
|
|
interface IFeeDistributor {
|
|
event TokenCheckpointed(IERC20 token, uint256 amount, uint256 lastCheckpointTimestamp);
|
|
event TokensClaimed(address user, IERC20 token, uint256 amount, uint256 userTokenTimeCursor);
|
|
|
|
/**
|
|
* @notice Returns the VotingEscrow (veBAL) token contract
|
|
*/
|
|
function getVotingEscrow() external view returns (IVotingEscrow);
|
|
|
|
/**
|
|
* @notice Returns the global time cursor representing the most earliest uncheckpointed week.
|
|
*/
|
|
function getTimeCursor() external view returns (uint256);
|
|
|
|
/**
|
|
* @notice Returns the user-level time cursor representing the most earliest uncheckpointed week.
|
|
* @param user - The address of the user to query.
|
|
*/
|
|
function getUserTimeCursor(address user) external view returns (uint256);
|
|
|
|
/**
|
|
* @notice Returns the token-level time cursor storing the timestamp at up to which tokens have been distributed.
|
|
* @param token - The ERC20 token address to query.
|
|
*/
|
|
function getTokenTimeCursor(IERC20 token) external view returns (uint256);
|
|
|
|
/**
|
|
* @notice Returns the user-level time cursor storing the timestamp of the latest token distribution claimed.
|
|
* @param user - The address of the user to query.
|
|
* @param token - The ERC20 token address to query.
|
|
*/
|
|
function getUserTokenTimeCursor(address user, IERC20 token) external view returns (uint256);
|
|
|
|
/**
|
|
* @notice Returns the user's cached balance of veBAL as of the provided timestamp.
|
|
* @dev Only timestamps which fall on Thursdays 00:00:00 UTC will return correct values.
|
|
* This function requires `user` to have been checkpointed past `timestamp` so that their balance is cached.
|
|
* @param user - The address of the user of which to read the cached balance of.
|
|
* @param timestamp - The timestamp at which to read the `user`'s cached balance at.
|
|
*/
|
|
function getUserBalanceAtTimestamp(address user, uint256 timestamp) external view returns (uint256);
|
|
|
|
/**
|
|
* @notice Returns the cached total supply of veBAL as of the provided timestamp.
|
|
* @dev Only timestamps which fall on Thursdays 00:00:00 UTC will return correct values.
|
|
* This function requires the contract to have been checkpointed past `timestamp` so that the supply is cached.
|
|
* @param timestamp - The timestamp at which to read the cached total supply at.
|
|
*/
|
|
function getTotalSupplyAtTimestamp(uint256 timestamp) external view returns (uint256);
|
|
|
|
/**
|
|
* @notice Returns the FeeDistributor's cached balance of `token`.
|
|
*/
|
|
function getTokenLastBalance(IERC20 token) external view returns (uint256);
|
|
|
|
/**
|
|
* @notice Returns the amount of `token` which the FeeDistributor received in the week beginning at `timestamp`.
|
|
* @param token - The ERC20 token address to query.
|
|
* @param timestamp - The timestamp corresponding to the beginning of the week of interest.
|
|
*/
|
|
function getTokensDistributedInWeek(IERC20 token, uint256 timestamp) external view returns (uint256);
|
|
|
|
// Depositing
|
|
|
|
/**
|
|
* @notice Deposits tokens to be distributed in the current week.
|
|
* @dev Sending tokens directly to the FeeDistributor instead of using `depositTokens` may result in tokens being
|
|
* retroactively distributed to past weeks, or for the distribution to carry over to future weeks.
|
|
*
|
|
* If for some reason `depositTokens` cannot be called, in order to ensure that all tokens are correctly distributed
|
|
* manually call `checkpointToken` before and after the token transfer.
|
|
* @param token - The ERC20 token address to distribute.
|
|
* @param amount - The amount of tokens to deposit.
|
|
*/
|
|
function depositToken(IERC20 token, uint256 amount) external;
|
|
|
|
/**
|
|
* @notice Deposits tokens to be distributed in the current week.
|
|
* @dev A version of `depositToken` which supports depositing multiple `tokens` at once.
|
|
* See `depositToken` for more details.
|
|
* @param tokens - An array of ERC20 token addresses to distribute.
|
|
* @param amounts - An array of token amounts to deposit.
|
|
*/
|
|
function depositTokens(IERC20[] calldata tokens, uint256[] calldata amounts) external;
|
|
|
|
// Checkpointing
|
|
|
|
/**
|
|
* @notice Caches the total supply of veBAL at the beginning of each week.
|
|
* This function will be called automatically before claiming tokens to ensure the contract is properly updated.
|
|
*/
|
|
function checkpoint() external;
|
|
|
|
/**
|
|
* @notice Caches the user's balance of veBAL at the beginning of each week.
|
|
* This function will be called automatically before claiming tokens to ensure the contract is properly updated.
|
|
* @param user - The address of the user to be checkpointed.
|
|
*/
|
|
function checkpointUser(address user) external;
|
|
|
|
/**
|
|
* @notice Assigns any newly-received tokens held by the FeeDistributor to weekly distributions.
|
|
* @dev Any `token` balance held by the FeeDistributor above that which is returned by `getTokenLastBalance`
|
|
* will be distributed evenly across the time period since `token` was last checkpointed.
|
|
*
|
|
* This function will be called automatically before claiming tokens to ensure the contract is properly updated.
|
|
* @param token - The ERC20 token address to be checkpointed.
|
|
*/
|
|
function checkpointToken(IERC20 token) external;
|
|
|
|
/**
|
|
* @notice Assigns any newly-received tokens held by the FeeDistributor to weekly distributions.
|
|
* @dev A version of `checkpointToken` which supports checkpointing multiple tokens.
|
|
* See `checkpointToken` for more details.
|
|
* @param tokens - An array of ERC20 token addresses to be checkpointed.
|
|
*/
|
|
function checkpointTokens(IERC20[] calldata tokens) external;
|
|
|
|
// Claiming
|
|
|
|
/**
|
|
* @notice Claims all pending distributions of the provided token for a user.
|
|
* @dev It's not necessary to explicitly checkpoint before calling this function, it will ensure the FeeDistributor
|
|
* is up to date before calculating the amount of tokens to be claimed.
|
|
* @param user - The user on behalf of which to claim.
|
|
* @param token - The ERC20 token address to be claimed.
|
|
* @return The amount of `token` sent to `user` as a result of claiming.
|
|
*/
|
|
function claimToken(address user, IERC20 token) external returns (uint256);
|
|
|
|
/**
|
|
* @notice Claims a number of tokens on behalf of a user.
|
|
* @dev A version of `claimToken` which supports claiming multiple `tokens` on behalf of `user`.
|
|
* See `claimToken` for more details.
|
|
* @param user - The user on behalf of which to claim.
|
|
* @param tokens - An array of ERC20 token addresses to be claimed.
|
|
* @return An array of the amounts of each token in `tokens` sent to `user` as a result of claiming.
|
|
*/
|
|
function claimTokens(address user, IERC20[] calldata tokens) external returns (uint256[] memory);
|
|
}
|