Description:
Proxy contract enabling upgradeable smart contract patterns. Delegates calls to an implementation contract.
Blockchain: Ethereum
Source Code: View Code On The Blockchain
Solidity Source Code:
{{
"language": "Solidity",
"sources": {
"src/modules/RevenueDistributionModule.sol": {
"content": "// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.8.20;
import {PausableUpgradeable} from "openzeppelin-contracts-upgradeable/utils/PausableUpgradeable.sol";
import {IERC20} from "openzeppelin-contracts/token/ERC20/IERC20.sol";
import {Math} from "openzeppelin-contracts/utils/math/Math.sol";
import {SafeERC20} from "openzeppelin-contracts/token/ERC20/utils/SafeERC20.sol";
import {IRevenueDistributionModule} from "src/interfaces/modules/IRevenueDistributionModule.sol";
import {IRegistryContract} from "src/interfaces/registry/IRegistryContract.sol";
import {IRegistryAccess} from "src/interfaces/registry/IRegistryAccess.sol";
import {CheckAccessControl} from "src/utils/CheckAccessControl.sol";
import {IEur0} from "src/interfaces/token/IEur0.sol";
import {ISEur0} from "src/interfaces/vaults/ISEur0.sol";
import {
PAUSING_CONTRACTS_ROLE,
UNPAUSING_CONTRACTS_ROLE,
CONTRACT_REGISTRY_ACCESS,
CONTRACT_EUR0,
OPERATOR_REVSWITCH_DISTRIBUTOR_ROLE,
OPERATOR_ACC_DT_DISTRIBUTOR_ROLE,
OPERATOR_REB_DT_DISTRIBUTOR_ROLE,
INITIAL_REVENUE_DISTRIBUTION_MINT_CAP,
OPERATOR_ADMIN_ROLE,
ONE_DAY,
ONE_WEEK,
BASIS_MILLION_POINT_BASE
} from "src/constants.sol";
import {
NullAddress,
DistributionToRebasingDTDisabled,
DistributionToAccruingDTDisabled,
DistributionToRevenueSwitchDisabled,
CannotDistributeEUR0ToRebasingDTMoreThanOnceADay,
CannotDistributeEUR0ToAccruingDTMoreThanOnceADay,
CannotDistributeEUR0ToRevenueSwitchMoreThanOnceAWeek,
NullContract,
SameValue,
AmountIsZero,
InsufficientSupply,
AmountTooBig,
MaxDailyAccruingMintAmount,
MaxDailyRebasingDTMintAmount,
MaxWeeklyRevSwitchMintAmount
} from "src/errors.sol";
/// @title RevenueDistributionModule
/// @notice Contract for automated minting and distribution of EUR0 tokens to three dedicated buckets
/// @dev This contract enables multipurpose revenue distribution with three fixed buckets:
/// 1. Revenue Switch
/// 2. Accruing Deposit Token
/// 3. Rebasing Deposit Token
/// @author Usual Labs
contract RevenueDistributionModule is PausableUpgradeable, IRevenueDistributionModule {
using CheckAccessControl for IRegistryAccess;
using SafeERC20 for IERC20;
using Math for uint256;
/*//////////////////////////////////////////////////////////////
STORAGE
//////////////////////////////////////////////////////////////*/
/// @custom:storage-location erc7201:RevenueDistributionModule.storage.v0
struct RevenueDistributionModuleStorageV0 {
/// Maximum amount of EUR0 that can be minted (mint cap)
uint256 operatorMintCap;
/// Last time revenue switch was distributed (weekly)
uint256 lastRevenueSwitchDistribution;
/// Last time accruing deposit token was distributed (daily)
uint256 lastAccruingDTDistribution;
/// Last time rebasing distribution token was distributed (daily)
uint256 lastRebasingDTDistribution;
/// The daily accruing yield rate in micro basis points (1 = 0.0001%)
uint256 dailyAccruingYieldRate;
/// Maximum amount of EUR0 that can be minted for revenue switch
uint256 maxRevSwitchMintCap;
/// Maximum amount of EUR0 that can be minted for accruing deposit token
uint256 maxAccruingMintCap;
/// Maximum amount of EUR0 that can be minted for rebasing distribution token
uint256 maxRebasingDTMintCap;
/// The address of the registry access contract
IRegistryAccess registryAccess;
/// The address of the EUR0 token contract
IEur0 eur0;
/// The address of the reward claim contract for rebasing distribution token
address rewardClaimForRebasingDT;
/// The address of the reward claim contract for revenue switch
address rewardClaimForRevenueSwitch;
/// The address of the reward claim contract for accruing deposit token
ISEur0 rewardClaimForAccruingDT;
/// Whether revenue switch distribution is paused
bool revenueSwitchDistributionPaused;
/// Whether accruing deposit token distribution is paused
bool accruingDTDistributionPaused;
/// Whether rebasing distribution token distribution is paused
bool rebasingDTDistributionPaused;
}
// keccak256(abi.encode(uint256(keccak256("RevenueDistributionModule.storage.v0")) - 1)) & ~bytes32(uint256(0xff))
// solhint-disable-next-line
bytes32 public constant RevenueDistributionModuleStorageV0Location =
0xe0542bbe30b10bf343060c7e797a9d2f82a63e9ef1d0b27e42754d313c510a00;
/// @notice Returns the storage struct of the contract
/// @return $ The storage struct
function _revenueDistributionModuleStorageV0()
internal
pure
returns (RevenueDistributionModuleStorageV0 storage $)
{
bytes32 position = RevenueDistributionModuleStorageV0Location;
// solhint-disable-next-line no-inline-assembly
assembly {
$.slot := position
}
}
/*//////////////////////////////////////////////////////////////
Constructor
//////////////////////////////////////////////////////////////*/
/// @custom:oz-upgrades-unsafe-allow constructor
constructor() {
_disableInitializers();
}
/*//////////////////////////////////////////////////////////////
Initializer
//////////////////////////////////////////////////////////////*/
/// @notice Initializes the contract with registry contract and yield module
/// @param _registryContract Address of the registry contract
/// @param _rewardClaimForRevenueSwitch Address of the reward claim contract for revenue switch
/// @param _rewardClaimForAccruingDT Address of the reward claim contract for accruing deposit token
/// @param _rewardClaimForRebasingDT Address of the reward claim contract for rebasing distribution token
/// @param _dailyAccruingYieldRate The daily accruing yield rate in micro basis points (1 = 0.0001%)
/// @param _maxRevSwitchMintCap The maximum amount of EUR0 that can be minted for revenue switch
/// @param _maxAccruingMintCap The maximum amount of EUR0 that can be minted for accruing deposit token
/// @param _maxRebasingDTMintCap The maximum amount of EUR0 that can be minted for rebasing distribution token
// solhint-disable-next-line code-complexity
function initialize(
address _registryContract,
address _rewardClaimForRevenueSwitch,
address _rewardClaimForAccruingDT,
address _rewardClaimForRebasingDT,
uint256 _dailyAccruingYieldRate,
uint256 _maxRevSwitchMintCap,
uint256 _maxAccruingMintCap,
uint256 _maxRebasingDTMintCap
) public initializer {
if (_registryContract == address(0)) {
revert NullContract();
}
if (_rewardClaimForRevenueSwitch == address(0)) {
revert NullAddress();
}
if (_rewardClaimForAccruingDT == address(0)) {
revert NullAddress();
}
if (_rewardClaimForRebasingDT == address(0)) {
revert NullAddress();
}
if (_dailyAccruingYieldRate > BASIS_MILLION_POINT_BASE) {
revert AmountTooBig();
}
if (_maxRevSwitchMintCap == 0) {
revert AmountIsZero();
}
if (_maxAccruingMintCap == 0) {
revert AmountIsZero();
}
if (_maxRebasingDTMintCap == 0) {
revert AmountIsZero();
}
RevenueDistributionModuleStorageV0 storage $ = _revenueDistributionModuleStorageV0();
__Pausable_init_unchained();
IRegistryContract registryContract = IRegistryContract(_registryContract);
$.registryAccess = IRegistryAccess(registryContract.getContract(CONTRACT_REGISTRY_ACCESS));
$.eur0 = IEur0(registryContract.getContract(CONTRACT_EUR0));
$.rewardClaimForRevenueSwitch = _rewardClaimForRevenueSwitch;
$.rewardClaimForAccruingDT = ISEur0(_rewardClaimForAccruingDT);
$.rewardClaimForRebasingDT = _rewardClaimForRebasingDT;
$.operatorMintCap = INITIAL_REVENUE_DISTRIBUTION_MINT_CAP;
$.maxRevSwitchMintCap = _maxRevSwitchMintCap;
$.maxAccruingMintCap = _maxAccruingMintCap;
$.maxRebasingDTMintCap = _maxRebasingDTMintCap;
// Initialize the three fixed distribution buckets
$.lastRevenueSwitchDistribution = block.timestamp;
$.lastAccruingDTDistribution = block.timestamp;
$.lastRebasingDTDistribution = block.timestamp;
$.dailyAccruingYieldRate = _dailyAccruingYieldRate;
}
/*//////////////////////////////////////////////////////////////
External
//////////////////////////////////////////////////////////////*/
/// @inheritdoc IRevenueDistributionModule
function distributeRevenueSwitch(uint256 amount) external whenNotPaused {
if (amount == 0) {
revert AmountIsZero();
}
RevenueDistributionModuleStorageV0 storage $ = _revenueDistributionModuleStorageV0();
$.registryAccess.onlyMatchingRole(OPERATOR_REVSWITCH_DISTRIBUTOR_ROLE);
// Check if revenue switch distribution is enabled
if ($.revenueSwitchDistributionPaused) {
revert DistributionToRevenueSwitchDisabled();
}
// Check if it's been at least a week since last distribution
if (block.timestamp - $.lastRevenueSwitchDistribution < ONE_WEEK) {
revert CannotDistributeEUR0ToRevenueSwitchMoreThanOnceAWeek(); // Too soon to distribute
}
// Check max revenue switch mint cap
if (amount > $.maxRevSwitchMintCap) {
revert MaxWeeklyRevSwitchMintAmount();
}
// Check mint cap
if (amount > $.operatorMintCap) {
revert InsufficientSupply();
}
// Reduce mint cap
$.operatorMintCap -= amount;
// Update last distribution time
$.lastRevenueSwitchDistribution = block.timestamp;
// Mint the amount to the reward claim contract
$.eur0.mint($.rewardClaimForRevenueSwitch, amount);
emit RevenueSwitchDistributed(amount, block.timestamp);
}
/// @inheritdoc IRevenueDistributionModule
/// @dev This function isn't subject to the operator mint cap
function distributeAccruingDT() external whenNotPaused {
RevenueDistributionModuleStorageV0 storage $ = _revenueDistributionModuleStorageV0();
// Check if accruing deposit token distribution is enabled
if ($.accruingDTDistributionPaused) {
revert DistributionToAccruingDTDisabled();
}
$.registryAccess.onlyMatchingRole(OPERATOR_ACC_DT_DISTRIBUTOR_ROLE);
// calculate the amount to distribute
uint256 amount = $.rewardClaimForAccruingDT.totalAssets().mulDiv(
$.dailyAccruingYieldRate, BASIS_MILLION_POINT_BASE, Math.Rounding.Floor
);
if (amount == 0) {
revert AmountIsZero();
}
// Check if it's been at least a day since last distribution
if (block.timestamp - $.lastAccruingDTDistribution < ONE_DAY) {
revert CannotDistributeEUR0ToAccruingDTMoreThanOnceADay();
}
// Check max accruing mint cap
if (amount > $.maxAccruingMintCap) {
revert MaxDailyAccruingMintAmount();
}
// Update last distribution time
$.lastAccruingDTDistribution = block.timestamp;
// Mint the amount to this contract
$.eur0.mint(address($.rewardClaimForAccruingDT), amount);
// Start yield distribution
$.rewardClaimForAccruingDT.startYieldDistribution(
amount, block.timestamp, block.timestamp + ONE_DAY
);
emit AccruingDTDistributed(amount, block.timestamp);
}
/// @inheritdoc IRevenueDistributionModule
function distributeRebasingDT(uint256 amount) external whenNotPaused {
if (amount == 0) {
revert AmountIsZero();
}
RevenueDistributionModuleStorageV0 storage $ = _revenueDistributionModuleStorageV0();
$.registryAccess.onlyMatchingRole(OPERATOR_REB_DT_DISTRIBUTOR_ROLE);
// Check if rebasing deposit token distribution is enabled
if ($.rebasingDTDistributionPaused) {
revert DistributionToRebasingDTDisabled();
}
// Check if it's been at least a day since last distribution
if (block.timestamp - $.lastRebasingDTDistribution < ONE_DAY) {
revert CannotDistributeEUR0ToRebasingDTMoreThanOnceADay();
}
// Check max rebasing deposit token mint cap
if (amount > $.maxRebasingDTMintCap) {
revert MaxDailyRebasingDTMintAmount();
}
// Check mint cap
if (amount > $.operatorMintCap) {
revert InsufficientSupply();
}
// Reduce mint cap
$.operatorMintCap -= amount;
// Update last distribution time
$.lastRebasingDTDistribution = block.timestamp;
// Mint the amount to the reward claim contract
$.eur0.mint($.rewardClaimForRebasingDT, amount);
emit RebasingDTDistributed(amount, block.timestamp);
}
/// @inheritdoc IRevenueDistributionModule
function setDailyAccruingYieldRate(uint256 newDailyRate) external whenNotPaused {
if (newDailyRate == 0) {
revert AmountIsZero();
}
if (newDailyRate > BASIS_MILLION_POINT_BASE) {
revert AmountTooBig();
}
RevenueDistributionModuleStorageV0 storage $ = _revenueDistributionModuleStorageV0();
$.registryAccess.onlyMatchingRole(OPERATOR_ADMIN_ROLE);
if (newDailyRate == $.dailyAccruingYieldRate) {
revert SameValue();
}
$.dailyAccruingYieldRate = newDailyRate;
emit DailyAccruingYieldRateUpdated(newDailyRate);
}
/// @inheritdoc IRevenueDistributionModule
function setOperatorMintCap(uint256 newMintCap) external whenNotPaused {
RevenueDistributionModuleStorageV0 storage $ = _revenueDistributionModuleStorageV0();
$.registryAccess.onlyMatchingRole(OPERATOR_ADMIN_ROLE);
uint256 oldMintCap = $.operatorMintCap;
if (newMintCap == oldMintCap) {
revert SameValue();
}
$.operatorMintCap = newMintCap;
emit OperatorMintCapUpdated(oldMintCap, newMintCap);
}
/// @inheritdoc IRevenueDistributionModule
function setMaxAccruingMintCap(uint256 newMaxAccruingMintCap) external whenNotPaused {
if (newMaxAccruingMintCap == 0) {
revert AmountIsZero();
}
RevenueDistributionModuleStorageV0 storage $ = _revenueDistributionModuleStorageV0();
$.registryAccess.onlyMatchingRole(OPERATOR_ADMIN_ROLE);
$.maxAccruingMintCap = newMaxAccruingMintCap;
emit MaxAccruingMintCapUpdated(newMaxAccruingMintCap);
}
/// @inheritdoc IRevenueDistributionModule
function setMaxRebasingDTMintCap(uint256 newMaxRebasingDTMintCap) external whenNotPaused {
if (newMaxRebasingDTMintCap == 0) {
revert AmountIsZero();
}
RevenueDistributionModuleStorageV0 storage $ = _revenueDistributionModuleStorageV0();
$.registryAccess.onlyMatchingRole(OPERATOR_ADMIN_ROLE);
$.maxRebasingDTMintCap = newMaxRebasingDTMintCap;
emit MaxRebasingDTMintCapUpdated(newMaxRebasingDTMintCap);
}
/// @inheritdoc IRevenueDistributionModule
function setMaxRevSwitchMintCap(uint256 newMaxRevSwitchMintCap) external whenNotPaused {
if (newMaxRevSwitchMintCap == 0) {
revert AmountIsZero();
}
RevenueDistributionModuleStorageV0 storage $ = _revenueDistributionModuleStorageV0();
$.registryAccess.onlyMatchingRole(OPERATOR_ADMIN_ROLE);
$.maxRevSwitchMintCap = newMaxRevSwitchMintCap;
emit MaxRevSwitchMintCapUpdated(newMaxRevSwitchMintCap);
}
/// @inheritdoc IRevenueDistributionModule
function setRewardClaimForRevenueSwitch(address newRewardClaim) external whenNotPaused {
if (newRewardClaim == address(0)) {
revert NullAddress();
}
RevenueDistributionModuleStorageV0 storage $ = _revenueDistributionModuleStorageV0();
$.registryAccess.onlyMatchingRole(OPERATOR_ADMIN_ROLE);
address oldRewardClaimContract = $.rewardClaimForRevenueSwitch;
if (oldRewardClaimContract == newRewardClaim) {
revert SameValue();
}
$.rewardClaimForRevenueSwitch = newRewardClaim;
emit RewardClaimForRevenueSwitchUpdated(oldRewardClaimContract, newRewardClaim);
}
/// @inheritdoc IRevenueDistributionModule
function setRewardClaimForAccruingDT(address newRewardClaim) external whenNotPaused {
if (newRewardClaim == address(0)) {
revert NullAddress();
}
RevenueDistributionModuleStorageV0 storage $ = _revenueDistributionModuleStorageV0();
$.registryAccess.onlyMatchingRole(OPERATOR_ADMIN_ROLE);
address oldRewardClaimContract = address($.rewardClaimForAccruingDT);
if (oldRewardClaimContract == newRewardClaim) {
revert SameValue();
}
$.rewardClaimForAccruingDT = ISEur0(newRewardClaim);
emit RewardClaimForAccruingDTUpdated(oldRewardClaimContract, address(newRewardClaim));
}
/// @inheritdoc IRevenueDistributionModule
function setRewardClaimForRebasingDT(address newRewardClaim) external whenNotPaused {
if (newRewardClaim == address(0)) {
revert NullAddress();
}
RevenueDistributionModuleStorageV0 storage $ = _revenueDistributionModuleStorageV0();
$.registryAccess.onlyMatchingRole(OPERATOR_ADMIN_ROLE);
address oldRewardClaimContract = $.rewardClaimForRebasingDT;
if (oldRewardClaimContract == newRewardClaim) {
revert SameValue();
}
$.rewardClaimForRebasingDT = newRewardClaim;
emit RewardClaimForRebasingDTUpdated(oldRewardClaimContract, newRewardClaim);
}
/// @inheritdoc IRevenueDistributionModule
function pauseRevenueSwitchDistribution() external {
RevenueDistributionModuleStorageV0 storage $ = _revenueDistributionModuleStorageV0();
$.registryAccess.onlyMatchingRole(PAUSING_CONTRACTS_ROLE);
if ($.revenueSwitchDistributionPaused == true) {
revert SameValue();
}
$.revenueSwitchDistributionPaused = true;
emit RevenueSwitchDistributionPaused();
}
/// @inheritdoc IRevenueDistributionModule
function pauseAccruingDTDistribution() external {
RevenueDistributionModuleStorageV0 storage $ = _revenueDistributionModuleStorageV0();
$.registryAccess.onlyMatchingRole(PAUSING_CONTRACTS_ROLE);
if ($.accruingDTDistributionPaused == true) {
revert SameValue();
}
$.accruingDTDistributionPaused = true;
emit AccruingDTDistributionPaused();
}
/// @inheritdoc IRevenueDistributionModule
function pauseRebasingDTDistribution() external {
RevenueDistributionModuleStorageV0 storage $ = _revenueDistributionModuleStorageV0();
$.registryAccess.onlyMatchingRole(PAUSING_CONTRACTS_ROLE);
if ($.rebasingDTDistributionPaused == true) {
revert SameValue();
}
$.rebasingDTDistributionPaused = true;
emit RebasingDTDistributionPaused();
}
/// @inheritdoc IRevenueDistributionModule
function unpauseRevenueSwitchDistribution() external {
RevenueDistributionModuleStorageV0 storage $ = _revenueDistributionModuleStorageV0();
$.registryAccess.onlyMatchingRole(UNPAUSING_CONTRACTS_ROLE);
if ($.revenueSwitchDistributionPaused == false) {
revert SameValue();
}
$.revenueSwitchDistributionPaused = false;
emit RevenueSwitchDistributionUnpaused();
}
/// @inheritdoc IRevenueDistributionModule
function unpauseAccruingDTDistribution() external {
RevenueDistributionModuleStorageV0 storage $ = _revenueDistributionModuleStorageV0();
$.registryAccess.onlyMatchingRole(UNPAUSING_CONTRACTS_ROLE);
if ($.accruingDTDistributionPaused == false) {
revert SameValue();
}
$.accruingDTDistributionPaused = false;
emit AccruingDTDistributionUnpaused();
}
/// @inheritdoc IRevenueDistributionModule
function unpauseRebasingDTDistribution() external {
RevenueDistributionModuleStorageV0 storage $ = _revenueDistributionModuleStorageV0();
$.registryAccess.onlyMatchingRole(UNPAUSING_CONTRACTS_ROLE);
if ($.rebasingDTDistributionPaused == false) {
revert SameValue();
}
$.rebasingDTDistributionPaused = false;
emit RebasingDTDistributionUnpaused();
}
/// @inheritdoc IRevenueDistributionModule
function pause() external {
RevenueDistributionModuleStorageV0 storage $ = _revenueDistributionModuleStorageV0();
$.registryAccess.onlyMatchingRole(PAUSING_CONTRACTS_ROLE);
_pause();
}
/// @inheritdoc IRevenueDistributionModule
function unpause() external {
RevenueDistributionModuleStorageV0 storage $ = _revenueDistributionModuleStorageV0();
$.registryAccess.onlyMatchingRole(UNPAUSING_CONTRACTS_ROLE);
_unpause();
}
/// @inheritdoc IRevenueDistributionModule
function getOperatorMintCap() external view returns (uint256) {
return _revenueDistributionModuleStorageV0().operatorMintCap;
}
/// @inheritdoc IRevenueDistributionModule
function getDailyAccruingYieldRate() external view returns (uint256) {
return _revenueDistributionModuleStorageV0().dailyAccruingYieldRate;
}
/// @inheritdoc IRevenueDistributionModule
function getRewardClaimContractForRevenueSwitch() external view returns (address) {
return _revenueDistributionModuleStorageV0().rewardClaimForRevenueSwitch;
}
/// @inheritdoc IRevenueDistributionModule
function getRewardClaimContractForAccruingDT() external view returns (address) {
return address(_revenueDistributionModuleStorageV0().rewardClaimForAccruingDT);
}
/// @inheritdoc IRevenueDistributionModule
function getRewardClaimContractForRebasingDT() external view returns (address) {
return _revenueDistributionModuleStorageV0().rewardClaimForRebasingDT;
}
/// @inheritdoc IRevenueDistributionModule
function getMaxRevSwitchMintCap() external view returns (uint256) {
return _revenueDistributionModuleStorageV0().maxRevSwitchMintCap;
}
/// @inheritdoc IRevenueDistributionModule
function getMaxAccruingMintCap() external view returns (uint256) {
return _revenueDistributionModuleStorageV0().maxAccruingMintCap;
}
/// @inheritdoc IRevenueDistributionModule
function getMaxRebasingDTMintCap() external view returns (uint256) {
return _revenueDistributionModuleStorageV0().maxRebasingDTMintCap;
}
/// @inheritdoc IRevenueDistributionModule
function isRevenueSwitchDistributionPaused() external view returns (bool) {
return _revenueDistributionModuleStorageV0().revenueSwitchDistributionPaused;
}
/// @inheritdoc IRevenueDistributionModule
function isAccruingDTDistributionPaused() external view returns (bool) {
return _revenueDistributionModuleStorageV0().accruingDTDistributionPaused;
}
/// @inheritdoc IRevenueDistributionModule
function isRebasingDTDistributionPaused() external view returns (bool) {
return _revenueDistributionModuleStorageV0().rebasingDTDistributionPaused;
}
}
"
},
"lib/openzeppelin-contracts-upgradeable/contracts/utils/PausableUpgradeable.sol": {
"content": "// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/Pausable.sol)
pragma solidity ^0.8.20;
import {ContextUpgradeable} from "../utils/ContextUpgradeable.sol";
import {Initializable} from "../proxy/utils/Initializable.sol";
/**
* @dev Contract module which allows children to implement an emergency stop
* mechanism that can be triggered by an authorized account.
*
* This module is used through inheritance. It will make available the
* modifiers `whenNotPaused` and `whenPaused`, which can be applied to
* the functions of your contract. Note that they will not be pausable by
* simply including this module, only once the modifiers are put in place.
*/
abstract contract PausableUpgradeable is Initializable, ContextUpgradeable {
/// @custom:storage-location erc7201:openzeppelin.storage.Pausable
struct PausableStorage {
bool _paused;
}
// keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.Pausable")) - 1)) & ~bytes32(uint256(0xff))
bytes32 private constant PausableStorageLocation = 0xcd5ed15c6e187e77e9aee88184c21f4f2182ab5827cb3b7e07fbedcd63f03300;
function _getPausableStorage() private pure returns (PausableStorage storage $) {
assembly {
$.slot := PausableStorageLocation
}
}
/**
* @dev Emitted when the pause is triggered by `account`.
*/
event Paused(address account);
/**
* @dev Emitted when the pause is lifted by `account`.
*/
event Unpaused(address account);
/**
* @dev The operation failed because the contract is paused.
*/
error EnforcedPause();
/**
* @dev The operation failed because the contract is not paused.
*/
error ExpectedPause();
/**
* @dev Initializes the contract in unpaused state.
*/
function __Pausable_init() internal onlyInitializing {
__Pausable_init_unchained();
}
function __Pausable_init_unchained() internal onlyInitializing {
PausableStorage storage $ = _getPausableStorage();
$._paused = false;
}
/**
* @dev Modifier to make a function callable only when the contract is not paused.
*
* Requirements:
*
* - The contract must not be paused.
*/
modifier whenNotPaused() {
_requireNotPaused();
_;
}
/**
* @dev Modifier to make a function callable only when the contract is paused.
*
* Requirements:
*
* - The contract must be paused.
*/
modifier whenPaused() {
_requirePaused();
_;
}
/**
* @dev Returns true if the contract is paused, and false otherwise.
*/
function paused() public view virtual returns (bool) {
PausableStorage storage $ = _getPausableStorage();
return $._paused;
}
/**
* @dev Throws if the contract is paused.
*/
function _requireNotPaused() internal view virtual {
if (paused()) {
revert EnforcedPause();
}
}
/**
* @dev Throws if the contract is not paused.
*/
function _requirePaused() internal view virtual {
if (!paused()) {
revert ExpectedPause();
}
}
/**
* @dev Triggers stopped state.
*
* Requirements:
*
* - The contract must not be paused.
*/
function _pause() internal virtual whenNotPaused {
PausableStorage storage $ = _getPausableStorage();
$._paused = true;
emit Paused(_msgSender());
}
/**
* @dev Returns to normal state.
*
* Requirements:
*
* - The contract must be paused.
*/
function _unpause() internal virtual whenPaused {
PausableStorage storage $ = _getPausableStorage();
$._paused = false;
emit Unpaused(_msgSender());
}
}
"
},
"lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol": {
"content": "// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.20;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
/**
* @dev Returns the value of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the value of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves a `value` amount of tokens from the caller's account to `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, uint256 value) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets a `value` amount of tokens as the allowance of `spender` over the
* caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 value) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the
* allowance mechanism. `value` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address from, address to, uint256 value) external returns (bool);
}
"
},
"lib/openzeppelin-contracts/contracts/utils/math/Math.sol": {
"content": "// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/math/Math.sol)
pragma solidity ^0.8.20;
/**
* @dev Standard math utilities missing in the Solidity language.
*/
library Math {
/**
* @dev Muldiv operation overflow.
*/
error MathOverflowedMulDiv();
enum Rounding {
Floor, // Toward negative infinity
Ceil, // Toward positive infinity
Trunc, // Toward zero
Expand // Away from zero
}
/**
* @dev Returns the addition of two unsigned integers, with an overflow flag.
*/
function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
uint256 c = a + b;
if (c < a) return (false, 0);
return (true, c);
}
}
/**
* @dev Returns the subtraction of two unsigned integers, with an overflow flag.
*/
function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b > a) return (false, 0);
return (true, a - b);
}
}
/**
* @dev Returns the multiplication of two unsigned integers, with an overflow flag.
*/
function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
if (a == 0) return (true, 0);
uint256 c = a * b;
if (c / a != b) return (false, 0);
return (true, c);
}
}
/**
* @dev Returns the division of two unsigned integers, with a division by zero flag.
*/
function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a / b);
}
}
/**
* @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
*/
function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a % b);
}
}
/**
* @dev Returns the largest of two numbers.
*/
function max(uint256 a, uint256 b) internal pure returns (uint256) {
return a > b ? a : b;
}
/**
* @dev Returns the smallest of two numbers.
*/
function min(uint256 a, uint256 b) internal pure returns (uint256) {
return a < b ? a : b;
}
/**
* @dev Returns the average of two numbers. The result is rounded towards
* zero.
*/
function average(uint256 a, uint256 b) internal pure returns (uint256) {
// (a + b) / 2 can overflow.
return (a & b) + (a ^ b) / 2;
}
/**
* @dev Returns the ceiling of the division of two numbers.
*
* This differs from standard division with `/` in that it rounds towards infinity instead
* of rounding towards zero.
*/
function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
if (b == 0) {
// Guarantee the same behavior as in a regular Solidity division.
return a / b;
}
// (a + b - 1) / b can overflow on addition, so we distribute.
return a == 0 ? 0 : (a - 1) / b + 1;
}
/**
* @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or
* denominator == 0.
* @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) with further edits by
* Uniswap Labs also under MIT license.
*/
function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {
unchecked {
// 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use
// use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
// variables such that product = prod1 * 2^256 + prod0.
uint256 prod0 = x * y; // Least significant 256 bits of the product
uint256 prod1; // Most significant 256 bits of the product
assembly {
let mm := mulmod(x, y, not(0))
prod1 := sub(sub(mm, prod0), lt(mm, prod0))
}
// Handle non-overflow cases, 256 by 256 division.
if (prod1 == 0) {
// Solidity will revert if denominator == 0, unlike the div opcode on its own.
// The surrounding unchecked block does not change this fact.
// See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.
return prod0 / denominator;
}
// Make sure the result is less than 2^256. Also prevents denominator == 0.
if (denominator <= prod1) {
revert MathOverflowedMulDiv();
}
///////////////////////////////////////////////
// 512 by 256 division.
///////////////////////////////////////////////
// Make division exact by subtracting the remainder from [prod1 prod0].
uint256 remainder;
assembly {
// Compute remainder using mulmod.
remainder := mulmod(x, y, denominator)
// Subtract 256 bit number from 512 bit number.
prod1 := sub(prod1, gt(remainder, prod0))
prod0 := sub(prod0, remainder)
}
// Factor powers of two out of denominator and compute largest power of two divisor of denominator.
// Always >= 1. See https://cs.stackexchange.com/q/138556/92363.
uint256 twos = denominator & (0 - denominator);
assembly {
// Divide denominator by twos.
denominator := div(denominator, twos)
// Divide [prod1 prod0] by twos.
prod0 := div(prod0, twos)
// Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.
twos := add(div(sub(0, twos), twos), 1)
}
// Shift in bits from prod1 into prod0.
prod0 |= prod1 * twos;
// Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such
// that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for
// four bits. That is, denominator * inv = 1 mod 2^4.
uint256 inverse = (3 * denominator) ^ 2;
// Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also
// works in modular arithmetic, doubling the correct bits in each step.
inverse *= 2 - denominator * inverse; // inverse mod 2^8
inverse *= 2 - denominator * inverse; // inverse mod 2^16
inverse *= 2 - denominator * inverse; // inverse mod 2^32
inverse *= 2 - denominator * inverse; // inverse mod 2^64
inverse *= 2 - denominator * inverse; // inverse mod 2^128
inverse *= 2 - denominator * inverse; // inverse mod 2^256
// Because the division is now exact we can divide by multiplying with the modular inverse of denominator.
// This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is
// less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1
// is no longer required.
result = prod0 * inverse;
return result;
}
}
/**
* @notice Calculates x * y / denominator with full precision, following the selected rounding direction.
*/
function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {
uint256 result = mulDiv(x, y, denominator);
if (unsignedRoundsUp(rounding) && mulmod(x, y, denominator) > 0) {
result += 1;
}
return result;
}
/**
* @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded
* towards zero.
*
* Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11).
*/
function sqrt(uint256 a) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
// For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.
//
// We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have
// `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.
//
// This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`
// → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`
// → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`
//
// Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.
uint256 result = 1 << (log2(a) >> 1);
// At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,
// since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at
// every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision
// into the expected uint128 result.
unchecked {
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
return min(result, a / result);
}
}
/**
* @notice Calculates sqrt(a), following the selected rounding direction.
*/
function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = sqrt(a);
return result + (unsignedRoundsUp(rounding) && result * result < a ? 1 : 0);
}
}
/**
* @dev Return the log in base 2 of a positive value rounded towards zero.
* Returns 0 if given 0.
*/
function log2(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 128;
}
if (value >> 64 > 0) {
value >>= 64;
result += 64;
}
if (value >> 32 > 0) {
value >>= 32;
result += 32;
}
if (value >> 16 > 0) {
value >>= 16;
result += 16;
}
if (value >> 8 > 0) {
value >>= 8;
result += 8;
}
if (value >> 4 > 0) {
value >>= 4;
result += 4;
}
if (value >> 2 > 0) {
value >>= 2;
result += 2;
}
if (value >> 1 > 0) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 2, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log2(value);
return result + (unsignedRoundsUp(rounding) && 1 << result < value ? 1 : 0);
}
}
/**
* @dev Return the log in base 10 of a positive value rounded towards zero.
* Returns 0 if given 0.
*/
function log10(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >= 10 ** 64) {
value /= 10 ** 64;
result += 64;
}
if (value >= 10 ** 32) {
value /= 10 ** 32;
result += 32;
}
if (value >= 10 ** 16) {
value /= 10 ** 16;
result += 16;
}
if (value >= 10 ** 8) {
value /= 10 ** 8;
result += 8;
}
if (value >= 10 ** 4) {
value /= 10 ** 4;
result += 4;
}
if (value >= 10 ** 2) {
value /= 10 ** 2;
result += 2;
}
if (value >= 10 ** 1) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 10, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log10(value);
return result + (unsignedRoundsUp(rounding) && 10 ** result < value ? 1 : 0);
}
}
/**
* @dev Return the log in base 256 of a positive value rounded towards zero.
* Returns 0 if given 0.
*
* Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.
*/
function log256(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 16;
}
if (value >> 64 > 0) {
value >>= 64;
result += 8;
}
if (value >> 32 > 0) {
value >>= 32;
result += 4;
}
if (value >> 16 > 0) {
value >>= 16;
result += 2;
}
if (value >> 8 > 0) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 256, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log256(value);
return result + (unsignedRoundsUp(rounding) && 1 << (result << 3) < value ? 1 : 0);
}
}
/**
* @dev Returns whether a provided rounding mode is considered rounding up for unsigned integers.
*/
function unsignedRoundsUp(Rounding rounding) internal pure returns (bool) {
return uint8(rounding) % 2 == 1;
}
}
"
},
"lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol": {
"content": "// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/utils/SafeERC20.sol)
pragma solidity ^0.8.20;
import {IERC20} from "../IERC20.sol";
import {IERC20Permit} from "../extensions/IERC20Permit.sol";
import {Address} from "../../../utils/Address.sol";
/**
* @title SafeERC20
* @dev Wrappers around ERC20 operations that throw on failure (when the token
* contract returns false). Tokens that return no value (and instead revert or
* throw on failure) are also supported, non-reverting calls are assumed to be
* successful.
* To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/
library SafeERC20 {
using Address for address;
/**
* @dev An operation with an ERC20 token failed.
*/
error SafeERC20FailedOperation(address token);
/**
* @dev Indicates a failed `decreaseAllowance` request.
*/
error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease);
/**
* @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeTransfer(IERC20 token, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeCall(token.transfer, (to, value)));
}
/**
* @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the
* calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.
*/
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeCall(token.transferFrom, (from, to, value)));
}
/**
* @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 oldAllowance = token.allowance(address(this), spender);
forceApprove(token, spender, oldAllowance + value);
}
/**
* @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no
* value, non-reverting calls are assumed to be successful.
*/
function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal {
unchecked {
uint256 currentAllowance = token.allowance(address(this), spender);
if (currentAllowance < requestedDecrease) {
revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease);
}
forceApprove(token, spender, currentAllowance - requestedDecrease);
}
}
/**
* @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval
* to be set to zero before setting it to a non-zero value, such as USDT.
*/
function forceApprove(IERC20 token, address spender, uint256 value) internal {
bytes memory approvalCall = abi.encodeCall(token.approve, (spender, value));
if (!_callOptionalReturnBool(token, approvalCall)) {
_callOptionalReturn(token, abi.encodeCall(token.approve, (spender, 0)));
_callOptionalReturn(token, approvalCall);
}
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*/
function _callOptionalReturn(IERC20 token, bytes memory data) private {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that
// the target address contains contract code and also asserts for success in the low-level call.
bytes memory returndata = address(token).functionCall(data);
if (returndata.length != 0 && !abi.decode(returndata, (bool))) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*
* This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.
*/
function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false
// and not revert is the subcall reverts.
(bool success, bytes memory returndata) = address(token).call(data);
return success && (returndata.length == 0 || abi.decode(returndata, (bool))) && address(token).code.length > 0;
}
}
"
},
"src/interfaces/modules/IRevenueDistributionModule.sol": {
"content": "// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.8.20;
interface IRevenueDistributionModule {
/*//////////////////////////////////////////////////////////////
Events
//////////////////////////////////////////////////////////////*/
/// @notice Emitted when revenue switch is distributed
event RevenueSwitchDistributed(uint256 amount, uint256 timestamp);
/// @notice Emitted when accruing deposit token is distributed
event AccruingDTDistributed(uint256 amount, uint256 timestamp);
/// @notice Emitted when rebasing distribution token is distributed
event RebasingDTDistributed(uint256 amount, uint256 timestamp);
/// @notice Emitted when the daily accruing yield rate is updated
event DailyAccruingYieldRateUpdated(uint256 newDailyAccruingYieldRate);
/// @notice Emitted when the operator mint cap is updated
event OperatorMintCapUpdated(uint256 oldMintCap, uint256 newMintCap);
/// @notice Emitted when the maximum amount of EUR0 that can be minted for revenue switch is updated
event MaxRevSwitchMintCapUpdated(uint256 newMaxRevSwitchMintCap);
/// @notice Emitted when the maximum amount of EUR0 that can be minted for accruing deposit token is updated
event MaxAccruingMintCapUpdated(uint256 newMaxAccruingMintCap);
/// @notice Emitted when the maximum amount of EUR0 that can be minted for rebasing distribution token is updated
event MaxRebasingDTMintCapUpdated(uint256 newMaxRebasingDTMintCap);
/// @notice Emitted when the reward claim contract for revenue switch is updated
event RewardClaimForRevenueSwitchUpdated(
address indexed oldRewardClaimContract, address indexed newRewardClaimContract
);
/// @notice Emitted when the reward claim contract for accruing deposit token is updated
event RewardClaimForAccruingDTUpdated(
address indexed oldRewardClaimContract, address indexed newRewardClaimContract
);
/// @notice Emitted when the reward claim contract for rebasing distribution token is updated
event RewardClaimForRebasingDTUpdated(
address indexed oldRewardClaimContract, address indexed newRewardClaimContract
);
/// @notice Emitted when revenue switch distribution is unpaused
event RevenueSwitchDistributionUnpaused();
/// @notice Emitted when revenue switch distribution is paused
event RevenueSwitchDistributionPaused();
/// @notice Emitted when accruing deposit token distribution is unpaused
event AccruingDTDistributionUnpaused();
/// @notice Emitted when accruing deposit token distribution is paused
event AccruingDTDistributionPaused();
/// @notice Emitted when rebasing distribution token distribution is paused
event RebasingDTDistributionPaused();
/// @notice Emitted when rebasing distribution token distribution is unpaused
event RebasingDTDistributionUnpaused();
/// @notice Distributes the revenue switch to the revenue switch bucket
/// @param amount The amount to distribute
/// @dev Can only be called by the OPERATOR_REVSWITCH_DISTRIBUTOR role
/// @dev The amount should be less than or equal to the mintCap
/// @dev The revenue switch bucket should be active
/// @dev This can only be called once a week and when not paused
function distributeRevenueSwitch(uint256 amount) external;
/// @notice Distributes the accruing deposit token to the accruing deposit token bucket
/// @dev The amount to distribute should be calculated by the function
/// @dev Can only be called by the OPERATOR_ACC_DT_DISTRIBUTOR role
/// @dev The amount should be less than or equal to the mintCap
/// @dev This can only be called once a day and when not paused
function distributeAccruingDT() external;
/// @notice Distributes the rebasing distribution token to the rebasing distribution token bucket
/// @param amount The amount to distribute
/// @dev Can only be called by the OPERATOR_REB_DT_DISTRIBUTOR role
/// @dev The amount should be less than or equal to the mintCap
/// @dev This can only be called once a day and when not paused
function distributeRebasingDT(uint256 amount) external;
/// @notice Sets the daily accruing yield rate
/// @param newDailyAccruingYieldRate The new daily accruing yield rate
/// @dev Can only be called by the OPERATOR_ADMIN_ROLE role
function setDailyAccruingYieldRate(uint256 newDailyAccruingYieldRate) external;
/// @notice Sets the mint cap for the overall mint cap
/// @param newMintCap New mint cap amount
/// @dev Can only be called by the OPERATOR_ADMIN_ROLE role
function setOperatorMintCap(uint256 newMintCap) external;
/// @notice Sets the maximum amount of EUR0 that can be minted for revenue switch
/// @param newMaxRevSwitchMintCap The new maximum amount of EUR0 that can be minted for revenue switch
/// @dev Can only be called by the OPERATOR_ADMIN_ROLE role
function setMaxRevSwitchMintCap(uint256 newMaxRevSwitchMintCap) external;
/// @notice Sets the maximum amount of EUR0 that can be minted for accruing deposit token
/// @param newMaxAccruingMintCap The new maximum amount of EUR0 that can be minted for accruing deposit token
/// @dev Can only be called by the OPERATOR_ADMIN_ROLE role
function setMaxAccruingMintCap(uint256 newMaxAccruingMintCap) external;
/// @notice Sets the maximum amount of EUR0 that can be minted for rebasing distribution token
/// @param newMaxRebasingDTMintCap The new maximum amount of EUR0 that can be minted for rebasing distribution token
/// @dev Can only be called by the OPERATOR_ADMIN_ROLE role
function setMaxRebasingDTMintCap(uint256 newMaxRebasingDTMintCap) external;
/// @notice Sets the reward claim contract address
/// @param newRewardClaimContract Address of the new reward claim contract for revenue switch
/// @dev Can only be called by the OPERATOR_ADMIN_ROLE role
function setRewardClaimForRevenueSwitch(address newRewardClaimContract) external;
/// @notice Sets the reward claim contract address for accruing deposit token
/// @param newRewardClaimContract Address of the new reward claim contract for accruing deposit token
/// @dev Can only be called by the OPERATOR_ADMIN_ROLE role
/// @dev The reward claim contract should implement ISEur0
function setRewardClaimForAccruingDT(address newRewardClaimContract) external;
/// @notice Sets the reward claim contract address for rebasing distribution token
/// @param newRewardClaimContract Address of the new reward claim contract for rebasing distribution token
/// @dev Can only be called by the OPERATOR_ADMIN_ROLE role
function setRewardClaimForRebasingDT(address newRewardClaimContract) external;
/// @notice Pauses all revenue distribution operations
/// @dev Can only be called by the PAUSING_CONTRACTS_ROLE role
function pause() external;
/// @notice Unpauses all revenue distribution operations
/// @dev Can only be called by the UNPAUSING_CONTRACTS_ROLE role
function unpause() external;
/// @notice Gets the current operator mint cap
/// @return operatorMintCap The current mint cap
function getOperatorMintCap() external view returns (uint256);
/// @notice Gets the daily accruing yield rate
/// @return dailyAccruingYieldRate The daily accruing yield rate
function getDailyAccruingYieldRate() external view returns (uint256 dailyAccruingYieldRate);
/// @notice Gets the reward claim contract address
/// @return rewardClaimContract The reward claim contract address for revenue switch
function getRewardClaimContractForRevenueSwitch() external view returns (address);
/// @notice Gets the reward claim contract address for accruing deposit token
/// @return rewardClaimContract The reward claim contract address for accruing deposit token
function getRewardClaimContractForAccruingDT() external view returns (address);
/// @notice Gets the reward claim contract address for rebasing distribution token
/// @return rewardClaimContract The reward claim contract address for rebasing distribution token
function getRewardClaimContractForRebasingDT() external view returns (address);
/// @notice Gets the maximum amount of EUR0 that can be minted for revenue switch
/// @return maxRevSwitchMintCap The maximum amount of EUR0 that can be minted for revenue switch
function getMaxRevSwitchMintCap() external view returns (uint256);
/// @notice Gets the maximum amount of EUR0 that can be minted for accruing deposit token
/// @return maxAccruingMintCap The maximum amount of EUR0 that can be minted for accruing deposit token
function getMaxAccruingMintCap() external view returns (uint256);
/// @notice Gets the maximum amount of EUR0 that can be minted for rebasing distribution token
/// @return maxRebasingDTMintCap The maximum amount of EUR0 that can be minted for rebasing distribution token
function getMaxRebasingDTMintCap() external view returns (uint256);
/// @notice Pauses revenue switch distribution
/// @dev Can only be called by the PAUSING_CONTRACTS_ROLE role
function pauseRevenueSwitchDistribution() external;
/// @notice Pauses accruing deposit token distribution
/// @dev Can only be called by the PAUSING_CONTRACTS_ROLE role
function pauseAccruingDTDistribution() external;
/// @notice Pauses rebasing distribution token distribution
/// @dev Can only be called by the PAUSING_CONTRACTS_ROLE role
function pauseRebasingDTDistribution() external;
/// @notice Unpauses revenue switch distribution
/// @dev Can only be called by the UNPAUSING_CONTRACTS_ROLE role
function unpauseRevenueSwitchDistribution() external;
/// @notice Unpauses accruing deposit token distribution
/// @dev Can only be called by the UNPAUSING_CONTRACTS_ROLE role
function unpauseAccruingDTDistribution() external;
/// @notice Unpauses rebasing distribution token distribution
/// @dev Can only be called by the UNPAUSING_CONTRACTS_ROLE role
function unpauseRebasingDTDistribution() external;
/// @notice Gets whether revenue switch distribution is paused
/// @return true if revenue switch distribution is paused, false otherwise
function isRevenueSwitchDistributionPaused() external view returns (bool);
/// @notice Gets whether accruing deposit token distribution is paused
/// @return true if accruing deposit token distribution is paused, false otherwise
function isAccruingDTDistributionPaused() external view returns (bool);
/// @notice Gets whether rebasing distribution token distribution is paused
/// @return true if rebasing distribution token distribution is paused, false otherwise
function isRebasingDTDistributionPaused() external view returns (bool);
}
"
},
"src/interfaces/registry/IRegistryContract.sol": {
"content": "// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.8.20;
interface IRegistryContract {
/*//////////////////////////////////////////////////////////////
Events
//////////////////////////////////////////////////////////////*/
/// @notice This event is emitted when the address of the contract is set
/// @param name The name of the contract in bytes32
/// @param contractAddress The address of the contract
event SetContract(bytes32 indexed name, address indexed contractAddress);
/*//////////////////////////////////////////////////////////////
Functions
//////////////////////////////////////////////////////////////*/
/// @notice Set the address of the contract
/// @param name
Submitted on: 2025-10-30 15:16:06
Comments
Log in to comment.
No comments yet.