Contract Source Code:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;
import {IOwnerFacet, SelectorsToFacet} from "src/interfaces/IOwnerFacet.sol";
import {LibOwner} from "src/libraries/LibOwner.sol";
import {LibEvents} from "src/libraries/LibEvents.sol";
import {LibErrors} from "src/libraries/LibErrors.sol";
/**
* @title OwnerFacet
* @dev Contract that provides ownership management functionality.
*/
contract OwnerFacet is IOwnerFacet {
/// @inheritdoc IOwnerFacet
function owner() external view returns (address) {
return LibOwner._getOwnerStorage().owner;
}
/// @inheritdoc IOwnerFacet
function pendingOwner() external view returns (address) {
return LibOwner._getOwnerStorage().pendingOwner;
}
/// @inheritdoc IOwnerFacet
function setSelectorToFacets(SelectorsToFacet[] calldata arr) external {
LibOwner.onlyOwner();
LibOwner.OwnerStorage storage s = LibOwner._getOwnerStorage();
for (uint256 i = 0; i < arr.length; i++) {
SelectorsToFacet memory selectorsToFacet = arr[i];
for (uint256 j = 0; j < selectorsToFacet.selectors.length; j++) {
s.selectorToFacet[selectorsToFacet.selectors[j]] = selectorsToFacet.facet;
emit LibEvents.SelectorToFacetSet(selectorsToFacet.selectors[j], selectorsToFacet.facet);
}
}
}
/// @inheritdoc IOwnerFacet
function selectorToFacet(bytes4 selector) external view returns (address) {
LibOwner.OwnerStorage storage s = LibOwner._getOwnerStorage();
return s.selectorToFacet[selector];
}
/// @inheritdoc IOwnerFacet
function transferOwnership(address newOwner) external {
LibOwner.onlyOwner();
LibOwner.OwnerStorage storage s = LibOwner._getOwnerStorage();
s.pendingOwner = newOwner;
emit LibEvents.OwnershipTransferStarted(s.owner, s.pendingOwner);
}
/// @inheritdoc IOwnerFacet
function acceptOwnership() external {
LibOwner.OwnerStorage storage s = LibOwner._getOwnerStorage();
address _pendingOwner = s.pendingOwner;
require(_pendingOwner == msg.sender, LibErrors.OwnableUnauthorizedAccount(msg.sender));
emit LibEvents.OwnershipTransferred(s.owner, _pendingOwner);
s.owner = _pendingOwner;
s.pendingOwner = address(0);
}
}
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity ^0.8.0;
struct SelectorsToFacet {
address facet;
bytes4[] selectors;
}
interface IOwnerFacet {
/**
* @dev Returns the address of the current owner.
* @return The address of the current owner.
*/
function owner() external view returns (address);
/**
* @dev Returns the address of the pending owner.
* @return The address of the pending owner.
*/
function pendingOwner() external view returns (address);
/**
* @dev Sets the mapping of function selectors to facet addresses.
* @param arr An array of SelectorsToFacet structs containing the selectors and their corresponding facet addresses.
*/
function setSelectorToFacets(SelectorsToFacet[] calldata arr) external;
/**
* @dev Returns the facet address for a given function selector.
* @param selector The function selector.
* @return The address of the facet.
*/
function selectorToFacet(bytes4 selector) external view returns (address);
/**
* @dev Initiates the transfer of ownership to a new owner.
* @param newOwner The address of the new owner.
*/
function transferOwnership(address newOwner) external;
/**
* @dev Accepts the transfer of ownership.
*/
function acceptOwnership() external;
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;
library LibErrors {
// ===================== OwnerFacet ================================
/**
* @dev The caller account is not authorized to perform an operation.
* @param account The address of the unauthorized account.
*/
error OwnableUnauthorizedAccount(address account);
/**
* @dev The function selector is invalid.
* @param selector The invalid function selector.
*/
error InvalidSelector(bytes4 selector);
// ===================== ClientsFacet ================================
/**
* @dev The owner address is already used by some client.
*/
error ClientOwnerReserved();
/**
* @dev The caller is not the client owner.
*/
error NotClientOwner();
/**
* @dev The project ID is out of bounds.
*/
error OutOfBoundProjectId();
/**
* @dev The project is already active.
*/
error ProjectActive();
/**
* @dev The client name is empty.
*/
error ClientNameEmpty();
/**
* @dev The client name is empty.
*/
error ReservedProjectsIsZero();
/**
* @dev The client name is already taken.
*/
error ClientNameTaken();
// ===================== FundsFacet ================================
/**
* @dev The project is inactive.
*/
error ProjectInactive();
/**
* @dev The function can only be called in a view context.
*/
error OnlyView();
/**
* @dev Compounding the underlying asset is forbidden.
*/
error CompoundUnderlyingForbidden();
/**
* @dev Position migration is forbidden.
*/
error PositionMigrationForbidden();
/**
* @dev There is not enough underlying assets in YelayLiteVault to cover redeem.
*/
error NotEnoughInternalFunds();
/**
* @dev Redeem doesn't pass minimum asset amount
*/
error MinRedeem();
// ===================== SwapWrapper ================================
/**
* @dev The token is not WETH.
*/
error NotWeth();
/**
* @dev No ETH available.
*/
error NoEth();
// ===================== ManagementFacet ================================
/**
* @dev The assets were not withdrawn from strategy.
*/
error StrategyNotEmpty();
/**
* @dev The strategy is already registered.
*/
error StrategyRegistered();
/**
* @dev The strategy is already active.
*/
error StrategyActive();
// ===================== LibPausable ================================
/**
* @dev The function is paused.
* @param selector The function selector that is paused.
*/
error Paused(bytes4 selector);
// ===================== Swapper ================================
/**
* @notice Used when trying to do a swap via an exchange that is not allowed to execute a swap.
* @param exchange Exchange used.
*/
error ExchangeNotAllowed(address exchange);
/**
* @notice Used when there is nothing to swap.
* @param tokenIn The token that was intended to be swapped.
*/
error NothingToSwap(address tokenIn);
/**
* @notice Used when nothing was swapped.
* @param tokenOut The token that was intended to be received.
*/
error NothingSwapped(address tokenOut);
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;
library LibEvents {
// FundsFacet
/**
* @dev Emitted when assets are deposited.
* @param projectId The ID of the project.
* @param sender The address of the sender.
* @param receiver The address of the receiver.
* @param assets The amount of assets deposited.
* @param shares The amount of shares minted.
*/
event Deposit(
uint256 indexed projectId, address indexed sender, address indexed receiver, uint256 assets, uint256 shares
);
/**
* @dev Emitted when assets are redeemed.
* @param projectId The ID of the project.
* @param sender The address of the sender.
* @param receiver The address of the receiver.
* @param assets The amount of assets redeemed.
* @param shares The amount of shares burned.
*/
event Redeem(
uint256 indexed projectId, address indexed sender, address indexed receiver, uint256 assets, uint256 shares
);
/**
* @dev Emitted when assets are deposited into a strategy.
* @param strategy The name of the strategy.
* @param amount The amount of assets deposited.
*/
event ManagedDeposit(bytes32 indexed strategy, uint256 amount);
/**
* @dev Emitted when assets are withdrawn from a strategy.
* @param strategy The name of the strategy.
* @param amount The amount of assets withdrawn.
*/
event ManagedWithdraw(bytes32 indexed strategy, uint256 amount);
/**
* @dev Emitted when interest is accrued.
* @param newTotalAssets The new total assets value.
* @param interest The amount of interest accrued.
* @param feeShares The amount of fee shares minted.
*/
event AccrueInterest(uint256 newTotalAssets, uint256 interest, uint256 feeShares);
/**
* @dev Emitted when the last total assets value is updated.
* @param lastTotalAssets The updated last total assets value.
*/
event UpdateLastTotalAssets(uint256 lastTotalAssets);
/**
* @dev Emitted when assets are compounded.
* @param amount The amount of assets compounded.
*/
event Compounded(uint256 amount);
/**
* @dev Emitted when a position is migrated.
* @param account The address of the account.
* @param fromProjectId The ID of the project from which the position is migrated.
* @param toProjectId The ID of the project to which the position is migrated.
* @param shares The amount of shares migrated.
*/
event PositionMigrated(
address indexed account, uint256 indexed fromProjectId, uint256 indexed toProjectId, uint256 shares
);
/**
* @dev Emitted when lastTotalAssetsUpdateInterval is updated.
* @param newInterval The new interval for updating lastTotalAssets.
*/
event UpdateLastTotalAssetsUpdateInterval(uint256 newInterval);
// ManagementFacet
/**
* @dev Emitted when the deposit queue is updated.
*/
event UpdateDepositQueue();
/**
* @dev Emitted when the withdraw queue is updated.
*/
event UpdateWithdrawQueue();
/**
* @dev Emitted when a strategy is added.
* @param strategy The address of the strategy.
* @param supplement Additional data for the strategy.
*/
event AddStrategy(address indexed strategy, bytes supplement);
/**
* @dev Emitted when a strategy is removed.
* @param strategy The address of the strategy.
* @param supplement Additional data for the strategy.
*/
event RemoveStrategy(address indexed strategy, bytes supplement);
/**
* @dev Emitted when a strategy is activate.
* @param strategy The address of the strategy.
* @param supplement Additional data for the strategy.
*/
event ActivateStrategy(address indexed strategy, bytes supplement);
/**
* @dev Emitted when a strategy is deactivated.
* @param strategy The address of the strategy.
* @param supplement Additional data for the strategy.
*/
event DeactivateStrategy(address indexed strategy, bytes supplement);
// ClientsFacet
/**
* @dev Emitted when new project IDs are assigned to a client.
* @param owner The address of the client owner.
* @param minProjectId The minimum project ID.
* @param maxProjectId The maximum project ID.
*/
event NewProjectIds(address indexed owner, uint256 minProjectId, uint256 maxProjectId);
/**
* @dev Emitted when project ownership is transferred.
* @param clientName The name of the client.
* @param oldOwner The address of the old owner.
* @param newOwner The address of the new owner.
*/
event ClientOwnershipTransfer(bytes32 indexed clientName, address indexed oldOwner, address indexed newOwner);
/**
* @dev Emitted when a project is activated.
* @param project The ID of the activated project.
*/
event ProjectActivated(uint256 indexed project);
// OwnerFacet
/**
* @dev Emitted when the ownership transfer process is started.
* @param previousOwner The address of the previous owner.
* @param newOwner The address of the new owner.
*/
event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);
/**
* @dev Emitted when the ownership transfer process is completed.
* @param previousOwner The address of the previous owner.
* @param newOwner The address of the new owner.
*/
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Emitted when a function selector is mapped to a facet.
* @param selector The function selector.
* @param facet The address of the facet.
*/
event SelectorToFacetSet(bytes4 indexed selector, address indexed facet);
// AccessFacet
/**
* @dev Emitted when a method is paused or unpaused.
* @param selector The function selector.
* @param paused The paused state.
*/
event PausedChange(bytes4 selector, bool paused);
// Swapper
/**
* @notice Emitted when the exchange allowlist is updated.
* @param exchange Exchange that was updated.
* @param isAllowed Whether the exchange is allowed to be used in a swap or not after the update.
*/
event ExchangeAllowlistUpdated(address indexed exchange, bool isAllowed);
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;
import {LibErrors} from "src/libraries/LibErrors.sol";
library LibOwner {
/**
* @custom:storage-location erc7201:yelay-vault.storage.OwnerFacet
* @custom:member owner The owner of the contract.
* @custom:member pendingOwner The address pending to become the owner.
* @custom:member selectorToFacet Mapping from selector to facet address.
*/
struct OwnerStorage {
address owner;
address pendingOwner;
mapping(bytes4 => address) selectorToFacet;
}
// keccak256(abi.encode(uint256(keccak256("yelay-vault.storage.OwnerFacet")) - 1)) & ~bytes32(uint256(0xff))
bytes32 private constant OWNER_STORAGE_LOCATION = 0x52b130868e76fc87849159cef46eb9bb0156aa8877197d318e4437829044d000;
function _getOwnerStorage() internal pure returns (OwnerStorage storage $) {
assembly {
$.slot := OWNER_STORAGE_LOCATION
}
}
/**
* @dev Reverts if the caller is not the owner.
*/
function onlyOwner() internal view {
OwnerStorage storage s = _getOwnerStorage();
require(s.owner == msg.sender, LibErrors.OwnableUnauthorizedAccount(msg.sender));
}
}