# GIP-0015: Allow passing a larger amount than available to unstake

**URL:** <https://forum.thegraph.com/t/gip-0015-allow-passing-a-larger-amount-than-available-to-unstake/2587>\
**Category:** Graph Improvement Proposals (GIP)\
**Tags:** protocol-gov\
**Created:** [September 30, 2021, 3:49am UTC](https://forum.thegraph.com/t/gip-0015-allow-passing-a-larger-amount-than-available-to-unstake/2587 "2021-09-30T03:49:32Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![ari](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.thegraph.com/ari/32/2747_2.png) [@ari](https://forum.thegraph.com/u/ari)\
**Post date:** [September 30, 2021, 3:49am UTC](https://forum.thegraph.com/t/gip-0015-allow-passing-a-larger-amount-than-available-to-unstake/2587/1 "2021-09-30T03:49:32Z")

</div>

The Staking contract verifies that an indexer never unstakes under the minimum indexer stake, if the indexer is going to do so, it must unstake _fully_ back to zero tokens. This condition combined with the use of the `stakeTo` function can be used to frontrun an indexer that is unstaking fully and make this action to revert.

# Motivation

Whenever an indexer unstakes, the Staking contract verifies that the stake is over `minimumIndexerStake`. Because of this, a partial unstake that is under the `minimumIndexerStake` will revert. There is a particular edge case where the unstake transaction can be frontrun leading to the indexer to fail to fully unstake.

The condition happens during following example sequence:

1. Indexer has _200,000_ staked tokens, the `minimumIndexerStake` is _100,000_

2. Indexer send a `unstake(200,000)` transaction to unstake fully.

3. A malicious actor sends a `stakeTo(indexerAddress, 1)` to stake just one token on the indexer address **right before transaction from item #2** gets mined.

4. The transaction from step **#2** gets mined and will **revert**. Even if the attacker is gifting tokens to the indexer it will make the unstake transaction to revert, because the contract will find the indexer has 200,001 tokens and by unstaking 200,000 it will be under the minimum stake.

# Specification

Allow the `unstake()` function to receive any amount of tokens to unstake, even larger than the current stake (like MAX\_UINT256). Then use `unstakeAmount = min(currentStake, unstakeAmount)` to get the actual unstake amount. This way we cap the unstake amount to the max staked tokens when the transaction gets processed and it doesn’t revert based on the passed amount.

# Implementation

See [@graphprotocol/contracts#487](https://github.com/graphprotocol/contracts/pull/487)

# Backwards Compatibility

The proposal is fully backwards compatible.

# Validation

### Audits

The implementation was audited by Consensys Diligence.

### Testnet

The implementation has not yet been deployed to Testnet.

---

<div class="post-metadata">

**Author:** ![Oliver](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.thegraph.com/oliver/32/631_2.png) [@Oliver](https://forum.thegraph.com/u/Oliver)\
**Post date:** [March 31, 2022, 6:24pm UTC](https://forum.thegraph.com/t/gip-0015-allow-passing-a-larger-amount-than-available-to-unstake/2587/2 "2022-03-31T18:24:51Z")

</div>

This GIP was implemented on 03/25/2022 as part of GGP-0007 and is now live
