> For the complete documentation index, see [llms.txt](https://documentation.kodiak.finance/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://documentation.kodiak.finance/developers/farms/smart-contract-reference.md).

# 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
