Skip to content
Protocol contracts not yet configured for this build
Enter app

Participant guides

Withdraw a matured position

At maturity, principal becomes withdrawable. Before maturity, it does not — this is enforced on chain, not by interface policy.

Maturity

A position stores unlockAt, set when it opens:

solidity
unlockAt = uint64(block.timestamp) + lockDuration

Withdrawal requires block.timestamp >= unlockAt. Any earlier attempt reverts:

solidity
if (block.timestamp < p.unlockAt) revert NotMatured(positionId, p.unlockAt);

The interface disables the Withdraw button until then and shows a live countdown, so a control is never offered that cannot succeed.

What you receive

One transaction returns both:

solidity
function withdraw(uint256 positionId) external returns (uint256 principal, uint256 rewards)
  • Principal — your full staked PLOUTO, exactly as deposited.
  • Rewards — any unclaimed ETH, paid in the same transaction.

There is no fee, no penalty and no rounding against you on principal. The amount returned is the amount deposited.

Steps

  1. Open Gravity. A matured position shows a Matured badge instead of a countdown.
  2. Select Withdraw.
  3. Sign, and watch through to Confirmed.
  4. The position closes and disappears from the list. totalStaked and totalWeight decrease accordingly.

There is no deadline

A matured position can sit open indefinitely. It keeps its full Gravity and keeps earning, exactly as before.

There is no penalty for leaving it, and no bonus. If you want to keep earning, doing nothing is a valid choice — though you are then holding weight with no lock, which you could equally re-commit for more.

Restaking

There is no automatic roll. To continue, withdraw and stake again — a new position with a new maturity.

Note that a new position opens at the current accumulator value, so it cannot claim rewards that accrued before it existed. There is no advantage lost by the gap, but also none gained.

Withdrawing is ordered safely

Effects before interactions, throughout:

solidity
rewards = _harvest(positionId, msg.sender);  // effects only, no transferprincipal = p.amount;uint256 weight = p.weight; p.amount = 0;p.weight = 0;totalStaked -= principal;totalWeight -= weight; emit Withdrawn(msg.sender, positionId, principal, rewards); IERC20(registry.ploutoToken()).safeTransfer(msg.sender, principal);if (rewards != 0) _sendEth(msg.sender, rewards);

The position is closed in storage before either transfer, and the whole function is nonReentrant. Withdrawing twice reverts with PositionClosed.

If withdrawal is paused

It is not. Pausing blocks new staking only; claims and matured withdrawals continue to work. See pausing.