Skip to content

VeniceStakingVault

Custodies DIEM and is the address under which the protocol stakes on Venice.

contracts/src/platforms/venice/VeniceStakingVault.sol

Implements / inherits

IPlatform, Ownable2Step, ReentrancyGuard

Constants

NameValue
EMERGENCY_DELAY7 days
ROLE_DELAY7 days
DAY1 days

Immutables

NameType
diemIDIEM (Venice DIEM token)

Mutable state

Wiring

NamePurpose
lockerAuthorized to call stake()
unstakeQueueAuthorized to call initiateUnstake(), claimUnstake(), transferOut()
pendingLocker, lockerEffectiveAtPending rotation buffer
pendingUnstakeQueue, unstakeQueueEffectiveAtPending rotation buffer

Daycap snapshot

NamePurpose
lastRolledDayLast UTC day for which capToday was frozen
capTodayInference capacity for the current UTC day (frozen)
nextDayCapLive preview of tomorrow's cap (== current Venice stake)

Emergency

NamePurpose
emergencyRecipientDrain destination
emergencyArmedAtuint64 timestamp when armEmergency was called
emergencyInitiatedbool — true after executeEmergencyInitiate
emergencyCoolDownEndVenice cooldown end when emergency unstake was initiated

Wiring setters

solidity
// One-shot (works only while role is address(0))
function setLockerInitial(address locker_) external onlyOwner;
function setUnstakeQueueInitial(address queue_) external onlyOwner;

// 7-day timelocked rotation
function proposeLocker(address locker_) external onlyOwner;
function activateLocker() external;
function cancelLockerChange() external onlyOwner;

function proposeUnstakeQueue(address queue_) external onlyOwner;
function activateUnstakeQueue() external;
function cancelUnstakeQueueChange() external onlyOwner;

Cross-checks on all variants: target's vault() must equal address(this).

Operational functions

solidity
function stake(uint256 amount)
    external onlyLocker whenNotEmergency nonReentrant;

function initiateUnstake(uint256 amount)
    external onlyUnstakeQueue whenNotEmergency nonReentrant
    returns (uint64 coolDownEnd_);

function claimUnstake()
    external onlyUnstakeQueue whenNotEmergency nonReentrant
    returns (uint256 drained);

function transferOut(address to, uint256 amount)
    external onlyUnstakeQueue whenNotEmergency nonReentrant;

IPlatform implementation

solidity
function dailyCap() external view returns (uint256);
// Returns capToday if same UTC day; nextDayCap if a new UTC day rolled.

This is what DailyAuction.settle reads to determine the next day's total available inference.

Views

solidity
function previewNextDayCap() external view returns (uint256);
function rollDay() external;                          // mutating no-op, public for keeper

function stakedAmount() external view returns (uint256);
function liveCoolDownEnd() external view returns (uint256);
function liveCoolDownAmount() external view returns (uint256);

Emergency

solidity
function armEmergency(address recipient) external onlyOwner;
function cancelEmergency() external onlyOwner;
function executeEmergencyInitiate() external onlyOwner nonReentrant;
function executeEmergencyDrain() external onlyOwner nonReentrant returns (uint256);

Flow described in Safety.

executeEmergencyDrain transfers the entire DIEM balance of the vault (claimed unstake + any free DIEM) to emergencyRecipient.

renounceOwnership overload

Requires locker != 0, unstakeQueue != 0, and no pending rotation changes. Prevents bricking via half-wired state or a pending hostile proposal at the moment of renounce.

Events

LockerProposed, LockerActivated, LockerChangeCancelled,
UnstakeQueueProposed, UnstakeQueueActivated, UnstakeQueueChangeCancelled,
DayRolled, NextDayCapRefreshed,
Staked, UnstakeInitiated, Unstaked, Transferred,
EmergencyArmed, EmergencyCancelled, EmergencyInitiated, EmergencyDrained

Why capToday is frozen

Venice's API allocates inference against stakedInfos[vault].amountStaked read at the epoch boundary (00:00 UTC). Once a UTC day has started, its inference budget is determined.

DailyAuction.settle() is called near the start of the inference day. It must read a cap that matches what Venice will actually allow. We freeze capToday so an initiateUnstake later in the day doesn't suddenly "shrink" the day's promised cap.

nextDayCap is the live preview that updates on every stake and initiateUnstake, so bidders see what's coming for tomorrow.

Released under the MIT License.