StakedIR
Inherits: ERC4626Upgradeable, ReentrancyGuardUpgradeable, Upgradeable
Title: StakedIR
ERC4626 vault for staking IR tokens with withdrawal ticket system
Rewards are auto-compounded (IR only after auction conversion)
Ticket system: Queued, time-based unlocks become claimable
State Variables
STAKED_IR_STORAGE_LOCATION
ERC-7201 storage location for StakedIR
keccak256(abi.encode(uint256(keccak256(bytes("infrared.stakedIRStorage"))) - 1)) & ~bytes32(uint256(0xff));
bytes32 private constant STAKED_IR_STORAGE_LOCATION =
0xe37d8c878a50f0326695af34a6b5c1ac8f3bc817d7b9727cc43175799b685e00
__gap
Reserve storage space for upgrades
uint256[40] private __gap
Functions
_stakedIRStorage
function _stakedIRStorage()
private
pure
returns (StakedIRStorage storage s);
Returns
| Name | Type | Description |
|---|---|---|
s | StakedIRStorage | The StakedIR storage struct |
constructor
Note: oz-upgrades-unsafe-allow: constructor
constructor() ;
initialize
Initialize the StakedIR contract
function initialize(IERC20 _ir, address _governance) external initializer;
Parameters
| Name | Type | Description |
|---|---|---|
_ir | IERC20 | The IR token address (asset) |
_governance | address | The Governance multisig address |
compound
Compound rewards (convert non-IR rewards via auction, then deposit)
Increases share value for all sIR holders
function compound(uint256 amount) external virtual nonReentrant;
Parameters
| Name | Type | Description |
|---|---|---|
amount | uint256 | Amount of IR tokens to compound |
setWithdrawalPeriod
Update fixed withdrawal period
Only callable by governance
function setWithdrawalPeriod(uint256 _newPeriod)
external
virtual
onlyGovernor;
Parameters
| Name | Type | Description |
|---|---|---|
_newPeriod | uint256 | The new withdrawal period in seconds |
_requestWithdraw
Request withdrawal by burning shares and queuing a ticket
Burns shares immediately and reserves assets
function _requestWithdraw(uint256 shares, address receiver, address owner)
internal
virtual
whenNotPaused
returns (uint256 assets);
Parameters
| Name | Type | Description |
|---|---|---|
shares | uint256 | Amount of shares to withdraw |
receiver | address | Address of recipient for withdrawn tokens |
owner | address | Address of token owner |
Returns
| Name | Type | Description |
|---|---|---|
assets | uint256 | Amount of assets reserved in the withdrawal request |
_claimWithdraw
Internal claim logic without reentrancy guard
function _claimWithdraw(uint256 requestId)
internal
virtual
returns (uint256 assets);
Parameters
| Name | Type | Description |
|---|---|---|
requestId | uint256 | The ID of the withdrawal request to claim |
Returns
| Name | Type | Description |
|---|---|---|
assets | uint256 | Amount of assets received |
claimWithdraw
Claim a matured withdrawal request
Auto-processes if still claimable
function claimWithdraw(uint256 requestId)
public
virtual
nonReentrant
returns (uint256 assets);
Parameters
| Name | Type | Description |
|---|---|---|
requestId | uint256 | The ID of the withdrawal request to claim |
Returns
| Name | Type | Description |
|---|---|---|
assets | uint256 | Amount of assets received |
claimBatch
Claim multiple matured withdrawal requests in one transaction
function claimBatch(uint256[] calldata requestIds)
external
virtual
nonReentrant
returns (uint256 total);
Parameters
| Name | Type | Description |
|---|---|---|
requestIds | uint256[] | Array of request IDs to claim |
Returns
| Name | Type | Description |
|---|---|---|
total | uint256 | Total assets received |
withdraw
Request withdrawal of assets (ERC4626 override)
Creates a withdrawal request instead of instant withdrawal
function withdraw(uint256 assets, address receiver, address owner)
public
virtual
override
returns (uint256 shares);
Parameters
| Name | Type | Description |
|---|---|---|
assets | uint256 | Amount of assets to withdraw |
receiver | address | Address to receive the withdrawn assets |
owner | address | Address of the share owner |
Returns
| Name | Type | Description |
|---|---|---|
shares | uint256 | Amount of shares burned |
redeem
Request redemption of shares (ERC4626 override)
Creates a withdrawal request instead of instant redemption
function redeem(uint256 shares, address receiver, address owner)
public
virtual
override
returns (uint256 assets);
Parameters
| Name | Type | Description |
|---|---|---|
shares | uint256 | Amount of shares to redeem |
receiver | address | Address to receive the withdrawn assets |
owner | address | Address of the share owner |
Returns
| Name | Type | Description |
|---|---|---|
assets | uint256 | Amount of assets reserved for withdrawal |
deposit
override to add whenNotPaused modifier
function deposit(uint256 assets, address receiver)
public
virtual
override
whenNotPaused
returns (uint256);
mint
override to add whenNotPaused modifier
function mint(uint256 shares, address receiver)
public
virtual
override
whenNotPaused
returns (uint256);
totalAssets
Total assets excluding reserved amounts for pending withdrawals
Returns liquid assets available for share calculations
function totalAssets() public view virtual override returns (uint256);
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | Total IR tokens held by vault minus reserved amounts |
totalCompounded
Get total rewards compounded since inception
function totalCompounded() external view virtual returns (uint256);
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | Total IR tokens compounded |
withdrawalPeriod
Get fixed withdrawal period
function withdrawalPeriod() external view virtual returns (uint256);
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | The withdrawal period in seconds |
totalReserved
Get total assets reserved for pending withdrawals
function totalReserved() external view virtual returns (uint256);
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | Total reserved assets |
requestLength
Get the current request length
function requestLength() external view virtual returns (uint256);
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | The number of withdrawal requests created |
requests
Get withdrawal request by ID
function requests(uint256 requestId)
external
view
virtual
returns (WithdrawalRequest memory);
Parameters
| Name | Type | Description |
|---|---|---|
requestId | uint256 | The request ID |
Returns
| Name | Type | Description |
|---|---|---|
<none> | WithdrawalRequest | The withdrawal request struct |
getQueuedAmount
Returns the total amount of assets queued for withdrawal across all unprocessed tickets
Checks for queued tckets and sums amounts
An edge case exists where this could be temporarily out if unlock time is decreased
function getQueuedAmount() public view returns (uint256 queuedAmount);
Returns
| Name | Type | Description |
|---|---|---|
queuedAmount | uint256 | The total assets in queue, not yet claimable |
getClaimableAmount
Returns the total amount of assets ready to be claimed
Calculated as total reserved minus queued amounts
function getClaimableAmount() external view returns (uint256 claimable);
Returns
| Name | Type | Description |
|---|---|---|
claimable | uint256 | The total assets that have passed unlock time and can be claimed |
getWithdrawalRequest
Get withdrawal request details
function getWithdrawalRequest(uint256 requestId)
external
view
virtual
returns (
bool claimed,
uint256 shares,
uint256 assets,
uint256 unlockTime,
address receiver
);
Parameters
| Name | Type | Description |
|---|---|---|
requestId | uint256 | The request ID |
Returns
| Name | Type | Description |
|---|---|---|
claimed | bool | The state of the request |
shares | uint256 | Amount of shares |
assets | uint256 | Amount of assets |
unlockTime | uint256 | When the request can be claimed |
receiver | address | The receiver address |
isWithdrawalReady
Check if a withdrawal request is ready to claim
function isWithdrawalReady(uint256 requestId)
external
view
virtual
returns (bool ready);
Parameters
| Name | Type | Description |
|---|---|---|
requestId | uint256 | The request ID |
Returns
| Name | Type | Description |
|---|---|---|
ready | bool | True if the request can be claimed |
previewUnlockTime
Preview the unlock time for a new request
function previewUnlockTime() external view returns (uint256);
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | The estimated unlock time |
getUserRequests
Get all withdrawal request IDs for a user
function getUserRequests(address user)
external
view
returns (uint256[] memory);
Parameters
| Name | Type | Description |
|---|---|---|
user | address | Address of the user |
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256[] | Array of request IDs belonging to the user |
Events
Compounded
Emitted when rewards are compounded into the vault
event Compounded(
address indexed compounder, uint256 amount, uint256 newTotalAssets
);
Parameters
| Name | Type | Description |
|---|---|---|
compounder | address | Address that triggered the compound |
amount | uint256 | Amount of IR tokens compounded |
newTotalAssets | uint256 | New total assets after compounding |
WithdrawalPeriodUpdated
Emitted when the withdrawal period is updated
event WithdrawalPeriodUpdated(uint256 oldPeriod, uint256 newPeriod);
Parameters
| Name | Type | Description |
|---|---|---|
oldPeriod | uint256 | Previous withdrawal period in seconds |
newPeriod | uint256 | New withdrawal period in seconds |
WithdrawalRequested
Emitted when a user requests a withdrawal
event WithdrawalRequested(
address indexed user,
uint256 indexed requestId,
uint256 shares,
uint256 unlockTime
);
Parameters
| Name | Type | Description |
|---|---|---|
user | address | Address of the user requesting withdrawal |
requestId | uint256 | ID of the withdrawal request |
shares | uint256 | Amount of shares burned |
unlockTime | uint256 | Timestamp when the withdrawal becomes claimable |
WithdrawalClaimed
Emitted when a withdrawal request is claimed
event WithdrawalClaimed(
address indexed user,
uint256 indexed requestId,
uint256 shares,
uint256 assets
);
Parameters
| Name | Type | Description |
|---|---|---|
user | address | Address that received the withdrawn assets |
requestId | uint256 | ID of the withdrawal request |
shares | uint256 | Amount of shares that were burned |
assets | uint256 | Amount of assets transferred |
Errors
WithdrawalNotReady
Thrown when attempting to claim a withdrawal before unlock time
error WithdrawalNotReady();
InvalidRequestId
Thrown when an invalid request ID is provided
error InvalidRequestId();
InvalidState
Thrown when a withdrawal request is in an invalid state
error InvalidState();
AmountTooLarge
Thrown when amount exceeds uint128 max
error AmountTooLarge();
TimestampOverflow
Thrown when timestamp calculation would overflow uint88
error TimestampOverflow();
Structs
WithdrawalRequest
Represents a withdrawal request in the global queue
Uses packed storage to optimize gas costs
struct WithdrawalRequest {
/// @notice Whether the withdrawal has been claimed
bool claimed;
/// @notice Timestamp when the withdrawal becomes claimable
uint88 unlockTime;
/// @notice Address that will receive the withdrawn assets
address receiver;
/// @notice Amount of shares that were burned
uint128 shares;
/// @notice Amount of assets reserved for withdrawal
uint128 assets;
}
StakedIRStorage
Storage struct for StakedIR using ERC-7201 pattern
Note: storage-location: erc7201:infrared.stakedIRStorage
struct StakedIRStorage {
/// @notice Total rewards compounded (for accounting)
uint256 totalCompounded;
/// @notice Fixed withdrawal period (default 7 days)
uint256 withdrawalPeriod;
/// @notice The current number of withdrawal requests queued (next requestId to be assigned)
uint256 requestLength;
/// @notice Mapping of request IDs to withdrawal request tickets
mapping(uint256 => WithdrawalRequest) requests;
/// @notice Total assets reserved for pending withdrawals (queued + processed)
uint256 totalReserved;
/// @notice Mapping of user addresses to their withdrawal request IDs
mapping(address => uint256[]) userRequests;
}