# Compound Staking Guide

This guide covers the TMS Compound Staking system, which uses two contracts together:

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

All user actions (deposit, withdraw, harvest) go through the **Vault** contract. Do not call stake, claim, or unstake on the MasterChef directly — your position is held by the Vault.

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

### Prerequisites

* Your MasterChef 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 MasterChef address:

1. Navigate to the MasterChef 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 MasterChef 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 MasterChef.

#### APY Calculation

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

***

### Part 1: Investor Guide

#### 1.1 — View Available Pools

On the **MasterChef** contract, navigate to "Read as Proxy".

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

Key fields:

* `apy`: Annual percentage yield (÷ 1000).
* `lockPeriodInDays`: Lock period. Cannot be 0.
* `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 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 — Approve Tokens

1. Go to the token contract.
2. Call `approve` with the **Vault** address and the amount you want to deposit.

#### 1.4 — Deposit

1. Navigate to the **Vault** contract on your block explorer.
2. Navigate to "Write as Proxy".
3. Connect your wallet.
4. Find `deposit`.
5. Enter:
   * `_pid`: The pool ID.
   * `_amount`: Amount to deposit (in wei).
6. 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.
7. Click Write and confirm the transaction.

You cannot deposit if the pool is full or if the current time is within `lockPeriodInDays` of the pool's `endDate`.

#### 1.5 — Check Your Position

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

Call `users` with pool ID and your address.

You will see:

* `shares`: Number of shares you hold in the pool.
* `totalInvested`: Total amount of tokens you have deposited (in wei).
* `totalClaimed`: Total amount of tokens you have claimed as rewards (in wei).
* `lastDepositedTime`: Timestamp of your last deposit.

Call `getRewardOfUser` with your address and pool ID to see your pending reward.

To calculate your total value: your value = (`shares` × `balanceOf`) / `totalShares`, where `balanceOf` and `totalShares` are read from the Vault using `balanceOf` with the pool ID and `pools` with the pool ID.

#### 1.6 — Check If You Can Withdraw

On the **Vault** contract, call `canUnstake` with your address and pool ID.

Returns `true` if your lock period has passed.

#### 1.7 — 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 the **Vault** contract on your block explorer.
2. Navigate to "Write as Proxy".
3. Connect your wallet.
4. To withdraw everything: call `withdrawAll` with `_pid` (pool ID).
5. To withdraw partially: call `withdraw` with `_pid` and `_shares` (number of shares to withdraw).
6. Click Write and confirm the transaction.

Your lock period must have passed before you can withdraw.

#### 1.8 — Harvest (Trigger Compounding)

Anyone can trigger compounding for a pool and earn a small call fee as a reward.

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

#### 1.9 — Check NFT Boost

On the **MasterChef** contract, navigate to "Read as Proxy".

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

NFT boosts are applied automatically when you withdraw from the Vault.

***

### Part 2: Admin / Founder Guide

Requires `MANAGER_ROLE` unless otherwise noted.

#### MasterChef Admin

**Grant / Revoke Manager**

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 value (÷ 1000).
* `_lockPeriodInDays`: Lock period in days (must be > 0).
* `_endDate`: Pool end date (Unix timestamp).
* `_hardCap`: Maximum deposit amount.
* `_token`: ERC-20 token address.

**Update a Pool**

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

**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).
* `_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 Admin

**Grant / Revoke Manager**

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/tms-contracts/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.
