# Smart Contract Reference

### Smart Contract Reference

#### Core Functions

`initialize`

```solidity
function initialize(
    address _owner,
    address _stakingToken,
    address[] memory _rewardTokens,
    address[] memory _rewardManagers,
    uint256[] memory _rewardRates,
    bytes calldata _data
) external nonReentrant
```

Initializes a new KodiakFarm instance.

**Parameters:**

* `_owner`: Address that will own the farm
* `_stakingToken`: Address of the token that can be staked
* `_rewardTokens`: Array of reward token addresses
* `_rewardManagers`: Array of managers for each reward token
* `_rewardRates`: Array of reward rates for each token
* `_data`: Additional initialization data (unused)

**Errors:**

* `Farm: Already initialized` - When farm already initialized
* `Farm: Array lengths do not match` - When input arrays have different lengths
* `Token already added` - When duplicate reward tokens provided

**Events:** None

***

`stakeLocked`

```solidity
function stakeLocked(
    uint256 liquidity,
    uint256 secs
) public nonReentrant
```

Stakes tokens with a time lock.

**Parameters:**

* `liquidity`: Amount of tokens to stake
* `secs`: Duration of the lock in seconds

**Emits:** `StakeLocked`

**Errors:**

* `Staking paused` - When staking is paused
* `Must stake more than zero` - When liquidity is 0
* `Farm cap exceeded` - When total staked would exceed cap
* `Address has been greylisted` - When user is greylisted
* `Minimum stake time not met` - When secs < lock\_time\_min
* `Trying to lock for too long` - When secs > lock\_time\_for\_max\_multiplier

***

`withdrawLocked`

```solidity
function withdrawLocked(
    bytes32 kek_id
) public nonReentrant withdrawalsNotPaused
```

Withdraws a specific locked stake.

**Parameters:**

* `kek_id`: Unique identifier of the stake to withdraw

**Emits:** `WithdrawLocked`

**Errors:**

* `Withdrawals paused` - When withdrawals are paused
* `Stake not found` - When kek\_id doesn't exist
* `Stake is still locked!` - When lock duration hasn't expired

***

`getReward`

```solidity
function getReward() 
external nonReentrant 
returns (uint256[] memory)
```

Claims all available reward tokens.

**Returns:**

* Array of claimed reward amounts for each reward token

**Emits:** `RewardPaid`

**Errors:**

* `Rewards collection paused` - When rewards collection is paused

***

`addNewRewardToken`

```solidity
function addNewRewardToken(
    address _rewardToken,
    address _rewardManager,
    uint256 _rewardRate
) external onlyOwnerOrFactoryOwner
```

Adds a new reward token to the farm.

**Parameters:**

* `_rewardToken`: Address of the new reward token
* `_rewardManager`: Address of the token's reward manager
* `_rewardRate`: Initial reward rate for the token

**Emits:**

* `RewardTokenAdded`
* `RewardRateUpdated`

**Errors:**

* `Zero address detected` - When \_rewardToken is zero address
* `Token already added` - When token already exists in farm

***

`setRewardRate`

```solidity
function setRewardRate(
    address _rewardToken,
    uint256 _rewardRate,
    bool sync_too
) external onlyTknMgrs(_rewardToken)
```

Updates the reward rate for a specific token.

**Parameters:**

* `_rewardToken`: Address of the reward token
* `_rewardRate`: New reward rate
* `sync_too`: Whether to sync rewards after rate change

**Emits:** `RewardRateUpdated`

**Errors:**

* `Farm: Not owner, factory owner, or tkn mgr` - When caller lacks permission

***

`emergencyWithdraw`

```solidity
function emergencyWithdraw(
    bytes32 kek_id
) public nonReentrant withdrawalsNotPaused
```

Emergency withdraws a stake without claiming rewards.

**Parameters:**

* `kek_id`: Unique identifier of the stake to withdraw

**Emits:** `WithdrawLocked`

**Errors:**

* `Withdrawals paused` - When withdrawals are paused
* `Stake not found` - When kek\_id doesn't exist

***

`recoverERC20`

```solidity
function recoverERC20(
    address tokenAddress,
    uint256 tokenAmount
) external onlyTknMgrs(tokenAddress)
```

Recovers mistakenly sent tokens from the contract.

**Parameters:**

* `tokenAddress`: Address of token to recover
* `tokenAmount`: Amount to recover

**Emits:**

* `Recovered`
* `RewardRateUpdated` (if reward token)

**Errors:**

* `Cannot rug staking / LP tokens` - When attempting to withdraw stake token
* `No valid tokens to recover` - When caller lacks permission for token

```solidity
function stakeLocked(uint256 liquidity, uint256 secs) public nonReentrant
```

Stakes tokens for a specified duration.

* `liquidity`: Amount of tokens to stake
* `secs`: Lock duration in seconds
* Requirements:
  * Staking not paused
  * Duration within min/max bounds
  * Address not greylisted
  * Within staking cap

```solidity
function withdrawLocked(bytes32 kek_id) public nonReentrant withdrawalsNotPaused
```

Withdraws a specific stake after lock period.

* `kek_id`: Unique identifier of the stake
* Requirements:
  * Lock period expired
  * Withdrawals not paused

**Reward Management**

```solidity
function getReward() external nonReentrant returns (uint256[] memory)
```

Claims all available rewards.

* Requirements:
  * Rewards collection not paused
* Returns array of claimed reward amounts

```solidity
function setRewardRate(
    address _rewardToken,
    uint256 _rewardRate,
    bool sync_too
) external onlyTknMgrs(_rewardToken)
```

Updates reward rate for a specific token.

* Requires manager privileges
* Auto-funds if rate increases
* Optionally syncs rewards

#### Administrative Functions

```solidity
function setMultipliers(uint256 _lock_max_multiplier) external onlyOwnerOrFactoryOwner
```

Updates the maximum lock multiplier.

* Must be >= 1e18 (1x)

```solidity
function addNewRewardToken(
    address _rewardToken,
    address _rewardManager,
    uint256 _rewardRate
) external onlyOwnerOrFactoryOwner
```

Adds a new reward token to the farm.

* Cannot add duplicate tokens
* Auto-funds rewards if farm active

#### Events

```solidity
event StakeLocked(address indexed user, uint256 amount, uint256 secs, bytes32 kek_id)
event WithdrawLocked(address indexed user, uint256 amount, bytes32 kek_id)
event RewardPaid(address indexed user, uint256 reward, address token_address)
```

#### Modifiers

```solidity
modifier onlyOwnerOrFactoryOwner()
modifier onlyTknMgrs(address reward_token_address)
modifier onlyFactoryOwner()
modifier notStakingPaused()
modifier withdrawalsNotPaused()
```

#### Role-Based Access Control

1. **Owner**
   * Set multipliers and durations
   * Add new reward tokens
   * Configure staking caps
   * Manage greylist
2. **Factory Owner**
   * Emergency controls
   * Pause withdrawals/rewards
   * Override lock restrictions
3. **Token Managers**
   * Manage specific reward tokens
   * Set reward rates
   * Recover mistaken tokens

#### Error Handling

Common error scenarios and their meanings:

```solidity
"Farm: not started yet" // Farm needs initialization
"Staking paused" // Administrative pause active
"Farm cap exceeded" // Total stake limit reached
"Stake is still locked!" // Lock duration not met
"Rewards collection paused" // Emergency pause on rewards
```

#### State Variables

Key state tracking:

```solidity
uint256 public stakingTokenCap;
uint256 public lock_max_multiplier;
uint256 public lock_time_for_max_multiplier;
uint256 private _total_liquidity_locked;
mapping(address => LockedStake[]) private lockedStakes;
```

#### Security Features

1. **Emergency Controls**
   * Pause staking/withdrawals/rewards
   * Emergency withdrawal option
   * Factory owner override
2. **Access Controls**
   * Multi-role system
   * Greylist functionality
   * Manager-specific permissions
3. **Economic Safety**
   * Dynamic reward adjustment
   * Staking caps
   * Lock time restrictions


---

# 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://documentation.kodiak.finance/developers/farms/smart-contract-reference.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.
