# V2 Compound staking Guide

This guide covers V2 Compound Staking, which uses two contracts together:

* **CompoundStaking** — The main staking contract. Handles deposits, APY-based compound interest, NFT boosts, and reinvesting. Supports two reward strategies.
* **Vault** — The auto-compounder. Deposits into CompoundStaking on your behalf, uses a shares model, supports deposit fees, and auto-harvests.

Both are V2 contracts with role-based access control (`MANAGER_ROLE`). If you are unsure which version you have, see the Staking Version Identification Guide.

Use the "Read as Proxy" and "Write as Proxy" tabs on the block explorer.

### Prerequisites

* Your CompoundStaking and/or Vault contract address.
* A block explorer for your chain (e.g., Etherscan, BscScan).
* A wallet (e.g., MetaMask) connected to the correct network.

### Key Concepts

#### Finding the Vault Address

Users interact with the **Vault** contract for deposits and withdrawals. If you only have the CompoundStaking address:

1. Navigate to the CompoundStaking contract on your block explorer.
2. Go to "Read as Proxy".
3. Call `compounderContract`.
4. The returned address is the Vault contract. Use this address for all deposit, withdraw, and harvest operations.

#### Reward Strategies

The CompoundStaking contract supports two reward strategies (set by admin):

| Strategy         | Value | Description                                                                      |
| ---------------- | ----- | -------------------------------------------------------------------------------- |
| lockNonexclusive | 0     | Rewards accrue during and after the lock period, up to pool end date.            |
| lockExclusive    | 1     | Rewards only accrue during the lock period. After lock expires, no more rewards. |

Check which strategy is active by calling `rewardsStrategy` on the CompoundStaking contract.

#### APY Calculation

APY is divided by 1000. So `120` = 12% APY. Rewards use compound interest — they grow exponentially.

***

### CompoundStaking — Direct Staking

Use this section if you are staking directly in CompoundStaking (not through the Vault).

#### Part 1: Investor Guide

**1.1 — View Available Pools**

Navigate to "Read as Proxy" on the CompoundStaking contract.

Call `getPools` or `poolInfo` with a pool index.

Key fields:

* `apy`: Annual percentage yield (divided by 1000, so 120 = 12%).
* `lockPeriodInDays`: Lock period.
* `totalDeposit`: Current total staked.
* `startDate` / `endDate`: Pool active period.
* `hardCap`: Max deposit.
* `token`: ERC-20 token for staking and rewards (same token).

**1.2 — Check Your Position**

Call `users` with pool ID and your address.

You will see:

* `totalInvested`: Amount staked (in wei).
* `totalWithdrawn`: Total rewards withdrawn.
* `totalClaimed`: Rewards claimed after fees.
* `lastPayout`: Timestamp of last claim.
* `depositTime`: When you last deposited.

**1.3 — Check Pending Rewards**

Call `payout` with `_pid` and `_addr`.

Returns pending reward amount in wei. Uses compound interest — rewards grow exponentially.

If `rewardsStrategy` is `lockExclusive`, rewards stop accruing when your lock period ends.

**1.4 — Check If You Can Claim / Unstake**

Call `canClaim` with `_pid` and `_addr`.

Returns `true` if your lock period has passed.

**1.5 — Check NFT Boost**

* Call `nftInfo` with pool ID. If `active` is `true`, a boost exists.
* Call `calcMultiplier` with `_pid` and your address — `10` = 1x, `15` = 1.5x.
* Call `ownsCorrectNFT` with your address and pool ID to verify eligibility.

**1.6 — Approve Tokens**

Go to the token contract and call `approve` with the CompoundStaking address.

**1.7 — Stake**

1. Navigate to "Write as Proxy" on CompoundStaking.
2. Call `stake` with `_pid` and `_amount` (in wei).

Cannot stake if pool is full or within `lockPeriodInDays` of `endDate`.

**1.8 — Claim**

Call `claim` with `_pid`. Or `claimAll`.

Lock period must have passed. A fee is deducted from rewards.

**1.9 — Reinvest**

Compound rewards back into the pool:

Call `reinvest` with `_pid`, or `reinvestAll`.

Does not require lock period to pass. Lock timer resets.

**1.10 — Unstake**

Call `unStake` with `_pid` and `_amount`.

Lock period must have passed. Rewards are auto-claimed.

#### Part 2: Admin Guide

Requires `MANAGER_ROLE`. Check with `hasRole`.

**Grant / Revoke Manager Role**

Requires `DEFAULT_ADMIN_ROLE`.

Call `setManagerRole` with `_user` and `_status` (true/false).

**Set Rewards Strategy**

Call `setRewardsStrategy` with:

* `0` = lockNonexclusive (rewards accrue after lock too).
* `1` = lockExclusive (rewards only during lock).

**Add a Pool**

Call `add` with:

* `_apy`: APY ÷ 1000 (e.g., 120 = 12%).
* `_lockPeriodInDays`: Lock period (must be > 0).
* `_endDate`: Unix timestamp.
* `_hardCap`: Max deposit in wei.
* `_token`: ERC-20 token address.

**Update a Pool**

Call `set` with `_pid`, `_apy`, `_lockPeriodInDays` (must be > 0), `_endDate`, `_hardCap`, `_maxTransfer`, and unused address param.

**Expire a Pool**

Call `set` and set `_endDate` to a past timestamp.

**Set NFT Boost**

Call `setNFT` with:

* `_pid`: Pool ID.
* `_name`: Name of the NFT.
* `_contractAdd`: NFT contract address (can only be set once).
* `_isUsed`: true to enable, false to disable.
* `_multiplier`: Multiplier value (base 10, so 15 = 1.5x). Must be >= 10.
* `_startIdx`: Start index of eligible NFT IDs.
* `_endIdx`: End index of eligible NFT IDs.

**Update Fees**

Call `updateFeeValues` with `_feePercent` (out of 1000) and `_feeWallet`.

**Update Compounder**

Call `updateCompounder` with Vault address. Can only be set once.

**Transfer Stuck Tokens**

Call `transferStuckToken` with `_token`, `_to`, and `_amount`.

Only allows transferring tokens that are not part of user deposits (checks reward balance).

***

### Vault — Auto-Compounder

The Vault stakes in CompoundStaking on your behalf. Your position is tracked in shares — as rewards compound, each share becomes worth more.

#### Part 1: Investor Guide

**1.1 — Approve Tokens**

Go to the token contract and call `approve` with the Vault address.

**1.2 — Check Deposit Fees**

There may be two types of fees when depositing through the Vault.

**Token Fee (Percentage)**

On the **Vault** contract, call `fee`.

* `depositFee`: Fee percentage out of 10,000 (e.g., 100 = 1%).
* `feeReceiver`: Address that receives the fee.

This fee is deducted from your deposit amount automatically.

**Native Token Fee (USD-denominated)**

On the **Vault** contract, call `minFeeUSD`. If greater than `0`, you must pay a fee in the chain's native token (ETH, BNB, etc.) when depositing.

The fee amount in wei is determined by the `feeConverter` contract at deposit time. You need to send this fee as the transaction value when calling `deposit`.

**1.3 — Deposit**

1. Navigate to "Write as Proxy" on the Vault.
2. Find `deposit`.
3. Enter:
   * `_pid`: The pool ID.
   * `_amount`: Amount to deposit (in wei).
4. If `minFeeUSD > 0`: Set the value (`payableAmount`) field. To find the correct amount:
   * Call `feeConverter` on the Vault to get the converter address.
   * On the converter contract, call `convertUSDFeeToWei` with the `minFeeUSD` value.
   * Use the returned value (or slightly more) as the transaction value.
5. Click Write and confirm the transaction.

**1.4 — Check Your Position**

On the Vault contract, navigate to "Read as Proxy".

Call `users` with pool ID and your address.

You will see:

* `shares`: Your share count.
* `totalInvested`: Total deposited.
* `totalClaimed`: Total claimed.
* `lastDepositedTime`: Timestamp of your last deposit.

Call `getRewardOfUser` with your address and pool ID for total reward.

To calculate your total value: call `balanceOf` with the pool ID and `pools` with the pool ID to get `totalShares`. Your value = (`shares` × `balanceOf`) / `totalShares`.

**1.5 — Check If You Can Withdraw**

Call `canUnstake` with your address and pool ID.

Returns `true` if your lock period has passed.

**1.6 — Withdraw**

Withdrawing from the Vault returns your principal plus any compounded rewards. There is no separate "claim" action — withdrawing is how you receive your rewards.

1. Navigate to "Write as Proxy" on the Vault.
2. To withdraw everything: call `withdrawAll` with `_pid`.
3. To withdraw partially: call `withdraw` with `_pid` and `_shares` (number of shares to withdraw).
4. Click Write and confirm the transaction.

Lock period must have passed before you can withdraw.

**1.7 — Harvest (Trigger Compounding)**

Anyone can trigger compounding and earn a small call fee:

* Call `harvest` with `_pid`, or `harvestAll` for all pools.
* Call `calculateHarvestDcbRewards` with `_pid` to see what you'd earn for triggering a harvest.

#### Part 2: Admin Guide

Requires `MANAGER_ROLE`.

**Grant / Revoke Manager Role**

Requires `DEFAULT_ADMIN_ROLE`.

Call `setManagerRole` with `_user` and `_status` (true/false).

**Set Call Fee**

Call `setCallFee` with `_callFee` (out of 10,000, so `25` = 0.25%).

**Set Deposit Fee**

Only callable by the current `feeReceiver`.

Call `setDepositFee` with `_feeReceiver` and `_depositFee` (out of 10,000).

**Set User Fee (Native Token / USD)**

Only callable by the current `feeReceiver`.

Call `setUsersFee` with:

* `_feeConverter`: Fee converter contract address.
* `_minFeeUSD`: Minimum fee in USD (8 decimals, where 1e8 = $1).

Set `_minFeeUSD` to `0` to disable the native token fee.

**Set Rewards Strategy**

Call `setRewardsStrategy` with:

* `0` = lockNonexclusive.
* `1` = lockExclusive.

**Withdraw Leftovers (lockExclusive only)**

After a pool has ended and all users have withdrawn, call `withdrawLeftovers` with `_pid` to recover remaining rewards.

Requirements:

* Pool must have 0 total shares remaining.
* Current time must be past the pool's end date.

**Pause / Unpause**

* Call `pause` to stop deposits and harvesting.
* Call `unpause` to resume.

**Transfer User Stake**

Call `transferUserStakeInfo` with:

* `from`: Original stake holder address.
* `to`: Destination address (must not already have shares in the pool).
* `pid`: Pool ID.
* `deadline`: Signature expiry timestamp.
* `signature`: Valid EIP-712 signature from the original stake holder.

**Transfer Stuck Tokens**

Call `transferStuckToken` with `_token`, `_to`, and `_amount`.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://tms-finance.gitbook.io/tms.finance/staking-contracts/v2-compound-staking-guide.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
