ShareManager
Overview
The ShareManager is an abstract upgradeable contract responsible for managing vault share issuance, allocation, whitelisting, permissions, and lockups in a modular vault system. It relies on a compact bitmask (flags) for enabling and disabling features and supports configurable per-account permissions.
Key Responsibilities
- Tracking total and active share supply.
- Enforcing a global unlock timestamp for burns, locks, and transfers.
- Verifying whitelist and transfer permissions.
- Enforcing mint, burn, and transfer pauses.
- Allocating and claiming shares through queues.
- Emitting granular control events on state transitions.
Roles and Permissions
Controlled through roles defined as:
SET_FLAGS_ROLE: Allows changing global flags (for example mint pause or whitelist enforcement).SET_ACCOUNT_INFO_ROLE: Grants permission to set per-account configuration.SET_WHITELIST_MERKLE_ROOT_ROLE: Grants permission to set new whitelist merkle root.- Queues allocate, lock, and burn shares. The vault or a queue can mint shares.
claimShares(account)is permissionless.setVaultis an unguarded, one-time setter; configuration must bind the intended vault.
Configuration and State
Storage
Storage is accessed via a deterministic slot generated by SlotLibrary.getSlot("ShareManager", name, version).
struct ShareManagerStorage {
address vault;
uint256 flags; // Encodes permissions and the global unlock timestamp
uint256 allocatedShares;
bytes32 whitelistMerkleRoot;
mapping(address => AccountInfo) accounts;
}
Behavior
Bitmask Controlled Features
Controlled via ShareManagerFlagLibrary:
hasMintPausehasBurnPausehasTransferPausehasWhitelisthasTransferWhitelistglobalLockup
globalLockup is a Unix timestamp. updateChecks rejects burns, locks, and transfers while block.timestamp < globalLockup. It does not apply this lockup to minting. There is no per-account lockup.
Functions
View Functions
vault(): Returns the vault address.sharesOf(account): Total shares (active + claimable).activeSharesOf(account): Abstract; must be implemented by child.claimableSharesOf(account): Reads from theIShareModule.totalShares():allocatedShares + activeShares().accounts(account): ReturnsAccountInfostruct (canDeposit,canTransfer,isBlacklisted).flags(): Decoded bitmask asFlagsstruct.whitelistMerkleRoot(): Current root used for off-chain whitelist proof verification.isDepositorWhitelisted(account, proof): RequirescanDepositwhenhasWhitelistis enabled, and a valid Merkle proof when the root is non-zero. Both conditions apply when both mechanisms are enabled.updateChecks(from, to): Reverts on violations (paused actions, lockups, blacklisting, etc.).
State-Changing Functions
setVault(...): Binds a non-zero vault once, without caller access control.setFlags(...): Updates global bitmask configuration.setWhitelistMerkleRoot(...): Updates whitelist merkle root.setAccountInfo(...): Sets access rights for an individual address.claimShares(...): Permissionlessly claims an account's shares through the vault'sIShareModule.allocateShares(...): Allocates shares for future minting (only callable by a queue).mintAllocatedShares(...): Mints shares from allocated pool to user.mint(...): Mints shares to an account; callable by the vault or a queue. The global lockup does not block minting.burn(...): Burns a user's shares (only queue).lock(account, value): Moves shares into the manager for a redemption (only queue), subject to burn checks.__ShareManager_init(...): Sets Merkle root at construction or upgrade.
Internal Hooks (Implemented by Child)
function _mintShares(address account, uint256 value) internal virtual;
function _burnShares(address account, uint256 value) internal virtual;
function _lockShares(address account, uint256 value) internal virtual;
These abstract functions allow concrete implementations to define how share balances are recorded or tokenized.