# UniswapV3Staker

A forked version of the UniswapV3Staker contract for use with the NFTX AMM.

## Table of Contents

<details>

<summary>Constants</summary>

[#factory](#factory "mention")\
[#nonfungiblepositionmanager](#nonfungiblepositionmanager "mention")\
[#maxincentiveduration](#maxincentiveduration "mention")\
[#maxincentivestartleadtime](#maxincentivestartleadtime "mention")

</details>

<details>

<summary>Variables</summary>

[#incentives](#incentives "mention")\
[#deposits](#deposits "mention")\
[#rewards](#rewards "mention")

</details>

<details>

<summary>Events</summary>

[#incentivecreated](#incentivecreated "mention")\
[#incentiveended](#incentiveended "mention")\
[#deposittransferred](#deposittransferred "mention")\
[#tokenstaked](#tokenstaked "mention")\
[#tokenunstaked](#tokenunstaked "mention")\
[#rewardclaimed](#rewardclaimed "mention")

</details>

<details>

<summary>Public Write Functions</summary>

[#createincentive](#createincentive "mention")\
[#endincentive](#endincentive "mention")\
[#onerc721received](#onerc721received "mention")\
[#transferdeposit](#transferdeposit "mention")\
[#withdrawtoken](#withdrawtoken "mention")\
[#staketoken](#staketoken "mention")\
[#unstaketoken](#unstaketoken "mention")\
[#claimreward](#claimreward "mention")

</details>

<details>

<summary>Read Functions</summary>

[#stakes](#stakes "mention")\
[#getrewardinfo](#getrewardinfo "mention")

</details>

## Constants

#### factory

```solidity
function factory() external view returns (IUniswapV3Factory)
```

The address of the NFTX AMM's pool factory.

#### nonfungiblePositionManager

```solidity
function nonfungiblePositionManager() 
    external 
    view 
    returns (INonfungiblePositionManager)
```

The address of the NFTX AMM's NonfungiblePositionManager.

#### maxIncentiveDuration

```solidity
function maxIncentiveDuration() external view returns (uint256)
```

The maximum duration of an incentive, in seconds.

#### maxIncentiveStartLeadTime

```solidity
function maxIncentiveStartLeadTime() external view returns (uint256)
```

The maximum amount of seconds into the future the incentive startTime can be set.

### Variables

#### incentives

```solidity
function incentives(bytes32 incentiveId)
    external
    view
    returns (
        uint256 totalRewardUnclaimed,
        uint160 totalSecondsClaimedX128,
        uint96 numberOfStakes
    )
```

Represents a staking incentive.&#x20;

<table><thead><tr><th width="240.33333333333331">Parameters</th><th width="177">Type</th><th>Description</th></tr></thead><tbody><tr><td>incentiveId</td><td><code>bytes32</code></td><td>The ID of the incentive computed from its parameters.</td></tr></tbody></table>

<table><thead><tr><th width="241.33333333333331">Return values</th><th width="177">Type</th><th>Description</th></tr></thead><tbody><tr><td>totalRewardUnclaimed</td><td><code>bytes32</code></td><td>The amount of reward token not yet claimed by users</td></tr><tr><td>totalSecondsClaimedX128</td><td><code>uint160</code></td><td>Total liquidity-seconds claimed, represented as a <code>UQ32.128</code></td></tr><tr><td>numberOfStakes</td><td><code>uint96</code></td><td>The count of deposits that are currently staked for the incentive.</td></tr></tbody></table>

#### deposits

```solidity
function deposits(uint256 tokenId)
    external
    view
    returns (
        address owner,
        uint48 numberOfStakes,
        int24 tickLower,
        int24 tickUpper
    )
```

Returns information about a deposited liquidity NFT.

<table><thead><tr><th width="212.33333333333331">Parameters</th><th width="177">Type</th><th>Description</th></tr></thead><tbody><tr><td>tokenId</td><td><code>uint256</code></td><td>The token ID of the liquidity NFT.</td></tr></tbody></table>

<table><thead><tr><th width="212.33333333333331">Return values</th><th width="177">Type</th><th>Description</th></tr></thead><tbody><tr><td>owner</td><td><code>address</code></td><td>The owner of the deposited liquidity NFT.</td></tr><tr><td>numberOfStakes</td><td><code>uint48</code></td><td>Counter of how many incentives for which the liquidity is staked.</td></tr><tr><td>tickLower</td><td><code>int24</code></td><td>The lower tick of the range.</td></tr><tr><td>tickUpper</td><td><code>int24</code></td><td>The upper tick of the range.</td></tr></tbody></table>

#### rewards

```solidity
function rewards(IERC20Minimal rewardToken, address owner) 
    external 
    view 
    returns (uint256 rewardsOwed)
```

Returns amounts of reward tokens owed to a given address according to the last time all stakes were updated.

<table><thead><tr><th width="212.33333333333331">Parameters</th><th width="177">Type</th><th>Description</th></tr></thead><tbody><tr><td>rewardToken</td><td><code>IERC20Minimal</code></td><td>The address of the token for which to check rewards.</td></tr><tr><td>owner</td><td><code>address</code></td><td>The owner for which the rewards owed are checked.</td></tr></tbody></table>

<table><thead><tr><th width="212.33333333333331">Return values</th><th width="177">Type</th><th>Description</th></tr></thead><tbody><tr><td>tokenId</td><td><code>uint256</code></td><td>The amount of the reward token claimable by the owner.</td></tr></tbody></table>

## Events

#### IncentiveCreated

```solidity
event IncentiveCreated(
    IERC20Minimal indexed rewardToken,
    IUniswapV3Pool indexed pool,
    uint256 startTime,
    uint256 endTime,
    address refundee,
    uint256 reward
)
```

Event emitted when a liquidity mining incentive has been created.

<table><thead><tr><th width="224.33333333333331">Parameters</th><th width="177">Type</th><th>Description</th></tr></thead><tbody><tr><td>rewardToken</td><td><code>IERC20Minimal</code></td><td>The token being distributed as a reward.</td></tr><tr><td>pool</td><td><code>IUniswapV3Pool</code></td><td>The NFTX AMM pool.</td></tr><tr><td>startTime</td><td><code>uint256</code></td><td>The time when the incentive program begins.</td></tr><tr><td>endTime</td><td><code>uint256</code></td><td>The time when rewards stop accruing.</td></tr><tr><td>refundee</td><td><code>uint256</code></td><td>The address that receives any remaining reward tokens after the end time.</td></tr><tr><td>reward</td><td><code>uint256</code></td><td>The amount of reward tokens to be distributed.</td></tr></tbody></table>

#### IncentiveEnded

```solidity
event IncentiveEnded(bytes32 indexed incentiveId, uint256 refund)
```

Event that can be emitted when a liquidity mining incentive has ended.

<table><thead><tr><th width="224.33333333333331">Parameters</th><th width="177">Type</th><th>Description</th></tr></thead><tbody><tr><td>incentiveId</td><td><code>bytes32</code></td><td>ID of the incentive that is ending.</td></tr><tr><td>refund</td><td><code>uint256</code></td><td>The amount of reward tokens refunded.</td></tr></tbody></table>

#### DepositTransferred

```solidity
event DepositTransferred(
    uint256 indexed tokenId, 
    address indexed oldOwner, 
    address indexed newOwner
)
```

Emitted when ownership of a deposit changes

<table><thead><tr><th width="224.33333333333331">Parameters</th><th width="177">Type</th><th>Description</th></tr></thead><tbody><tr><td>tokenId</td><td><code>uint256</code></td><td>The token ID of the deposited liquidity NFT that is being transferred.</td></tr><tr><td>oldOwner</td><td><code>address</code></td><td>The owner before the deposit was transferred.</td></tr><tr><td>newOwner</td><td><code>address</code></td><td>The owner after the deposit was transferred.</td></tr></tbody></table>

#### TokenStaked

```solidity
event TokenStaked(
    uint256 indexed tokenId, 
    bytes32 indexed incentiveId, 
    uint128 liquidity
)
```

Event emitted when an NFTX AMM LP token has been staked.

<table><thead><tr><th width="224.33333333333331">Parameters</th><th width="177">Type</th><th>Description</th></tr></thead><tbody><tr><td>tokenId</td><td><code>uint256</code></td><td>The token ID of the staked liquidity NFT.</td></tr><tr><td>incentiveId</td><td><code>bytes32</code></td><td>ID of the incentive being staked on. </td></tr><tr><td>liquidity</td><td><code>uint128</code></td><td>The amount of liquidity staked.</td></tr></tbody></table>

#### TokenUnstaked

```solidity
event TokenUnstaked(uint256 indexed tokenId, bytes32 indexed incentiveId)
```

Event emitted when an NFTX AMM liquidity NFT has been unstaked.

<table><thead><tr><th width="224.33333333333331">Parameters</th><th width="177">Type</th><th>Description</th></tr></thead><tbody><tr><td>tokenId</td><td><code>uint256</code></td><td>The token ID of the unstaked liquidity NFT.</td></tr><tr><td>incentiveId</td><td><code>bytes32</code></td><td>ID of the incentive being unstaked from.</td></tr></tbody></table>

#### RewardClaimed

```solidity
event RewardClaimed(address indexed to, uint256 reward)
```

Event emitted when a reward token has been claimed.

<table><thead><tr><th width="224.33333333333331">Parameters</th><th width="177">Type</th><th>Description</th></tr></thead><tbody><tr><td>to</td><td><code>address</code></td><td>The address that claimed rewards were sent to.</td></tr><tr><td>reward</td><td><code>uint256</code></td><td>The amount of reward token claimed.</td></tr></tbody></table>

## Write Functions

#### constructor

```solidity
function constructor(
    contract IUniswapV3Factory _factory,
    contract INonfungiblePositionManager _nonfungiblePositionManager,
    uint256 _maxIncentiveStartLeadTime,
    uint256 _maxIncentiveDuration
) public
```

<table><thead><tr><th width="276.3333333333333">Parameters</th><th width="203">Type</th><th>Description</th></tr></thead><tbody><tr><td>_factory</td><td><code>contract IUniswapV3Factory</code></td><td>The Uniswap V3 factory.</td></tr><tr><td>_nonfungiblePositionManager</td><td><code>contract INonfungiblePositionManager</code></td><td>The NFT position manager contract address.</td></tr><tr><td>_maxIncentiveStartLeadTime</td><td><code>uint256</code></td><td>The max duration of an incentive in seconds.</td></tr><tr><td>_maxIncentiveDuration</td><td><code>uint256</code></td><td>The max amount of seconds into the future the incentive startTime can be set.</td></tr></tbody></table>

#### createIncentive

```solidity
function createIncentive(IncentiveKey memory key, uint256 reward) external 
```

Creates a new liquidity mining incentive program.

<table><thead><tr><th width="192.33333333333331">Parameters</th><th width="157">Type</th><th>Description</th></tr></thead><tbody><tr><td>key</td><td><code>IncentiveKey</code></td><td>Details of the incentive to create.</td></tr><tr><td>reward</td><td><code>uint256</code></td><td>The amount of reward tokens to be distributed.</td></tr></tbody></table>

#### endIncentive

```solidity
function endIncentive(IncentiveKey memory key) 
    external 
    returns (uint256 refund)
```

Ends an incentive after the incentive end time has passed and all stakes have been withdrawn.

<table><thead><tr><th width="192.5">Parameters</th><th width="157">Type</th><th>Description</th></tr></thead><tbody><tr><td>key</td><td><code>IncentiveKey</code></td><td>Details of the incentive to end.</td></tr></tbody></table>

<table><thead><tr><th width="192.5">Return values</th><th width="160">Type</th><th>Description</th></tr></thead><tbody><tr><td>refund</td><td><code>uint256</code></td><td>The remaining reward tokens when the incentive is ended.</td></tr></tbody></table>

#### onERC721Received

```solidity
function onERC721Received(
    address,
    address from,
    uint256 tokenId,
    bytes calldata data
) external returns (bytes4)
```

Upon receiving a NFTX  V3 LP ERC721, creates the token deposit setting owner to `from`. Also stakes token in one or more incentives if properly formatted `data` has a length > 0.

Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} by `operator` from `from`, this function is called. It must return its Solidity selector to confirm the token transfer. If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`.

<table><thead><tr><th width="192.5">Parameters</th><th width="137">Type</th><th>Description</th></tr></thead><tbody><tr><td><em>unnamed</em></td><td><code>address</code></td><td>The address which called the transfer function.</td></tr><tr><td>from</td><td><code>address</code></td><td>The address which previously owned the token.</td></tr><tr><td>tokenId</td><td><code>uint256</code></td><td>ID of the NFT.</td></tr><tr><td>data</td><td><code>bytes</code></td><td>Additional data with no specified format.</td></tr></tbody></table>

<table><thead><tr><th width="192.5">Return values</th><th width="140">Type</th><th>Description</th></tr></thead><tbody><tr><td><em>unnamed</em></td><td><code>bytes4</code></td><td>A keccak256 hash of the function call and arguments.</td></tr></tbody></table>

#### transferDeposit

```solidity
function transferDeposit(uint256 tokenId, address to) external
```

Transfers ownership of a deposit from the sender to the given recipient.

<table><thead><tr><th width="192.5">Parameters</th><th width="157">Type</th><th>Description</th></tr></thead><tbody><tr><td>tokenId</td><td><code>uint256</code></td><td>The ID of the token (and the deposit) to transfer.</td></tr><tr><td>to</td><td><code>address</code></td><td>The new owner of the deposit.</td></tr></tbody></table>

#### withdrawToken

```solidity
function withdrawToken(uint256 tokenId, address to, bytes memory data) external
```

Withdraws an NFTX V3 LP token `tokenId` from this contract to the recipient `to`.

<table><thead><tr><th width="192.5">Parameters</th><th width="157">Type</th><th>Description</th></tr></thead><tbody><tr><td>tokenId</td><td><code>uint256</code></td><td>The unique identifier of an Uniswap V3 LP token.</td></tr><tr><td>to</td><td><code>address</code></td><td>The address where the LP token will be sent.</td></tr><tr><td>data</td><td><code>bytes</code></td><td>An optional data array that will be passed along to the <code>to</code> address via the NFT safeTransferFrom.</td></tr></tbody></table>

#### stakeToken

```solidity
function stakeToken(IncentiveKey memory key, uint256 tokenId) external override
```

Stakes an NFTX V3 LP token.

<table><thead><tr><th width="192.5">Parameters</th><th width="157">Type</th><th>Description</th></tr></thead><tbody><tr><td>key</td><td><code>IncentiveKey</code></td><td>The key of the incentive for which to stake the NFT.</td></tr><tr><td>tokenId</td><td><code>uint256</code></td><td>The ID of the token to stake.</td></tr></tbody></table>

#### unstakeToken

```solidity
function unstakeToken(IncentiveKey memory key, uint256 tokenId) external override
```

Unstakes an NFTX V3 LP token.

<table><thead><tr><th width="192.5">Parameters</th><th width="157">Type</th><th>Description</th></tr></thead><tbody><tr><td>key</td><td><code>IncentiveKey</code></td><td>The key of the incentive for which to unstake the NFT.</td></tr><tr><td>tokenId</td><td><code>uint256</code></td><td>The ID of the token to unstake.</td></tr></tbody></table>

#### claimReward

```solidity
function claimReward(
    IERC20Minimal rewardToken,
    address to,
    uint256 amountRequested
) external returns (uint256 reward)
```

Transfers `amountRequested` of accrued `rewardToken` rewards from the contract to the recipient `to`.

<table><thead><tr><th width="192.5">Parameters</th><th width="166">Type</th><th>Description</th></tr></thead><tbody><tr><td>rewardToken</td><td><code>IERC20Minimal</code></td><td>The token being distributed as a reward.</td></tr><tr><td>to</td><td><code>address</code></td><td>The address where claimed rewards will be sent.</td></tr><tr><td>amountRequested</td><td><code>uint256</code></td><td>The amount of reward token to claim. If set to 0, then the entire reward amount is claimed.</td></tr></tbody></table>

<table><thead><tr><th width="192.5">Return values</th><th width="160">Type</th><th>Description</th></tr></thead><tbody><tr><td>reward</td><td><code>uint256</code></td><td>The amount of reward token claimed.</td></tr></tbody></table>

## Read Functions

#### stakes

```solidity
function stakes(uint256 tokenId, bytes32 incentiveId)
    public
    view
    override
    returns (uint160 secondsPerLiquidityInsideInitialX128, uint128 liquidity)
```

Returns information about a staked liquidity NFT.

<table><thead><tr><th width="192.5">Parameters</th><th width="166">Type</th><th>Description</th></tr></thead><tbody><tr><td>tokenId</td><td><code>uint256</code></td><td>The ID of the staked token.</td></tr><tr><td>incentiveId</td><td><code>bytes32</code></td><td>The ID of the incentive for which the token is staked.</td></tr></tbody></table>

<table><thead><tr><th width="198.5">Return values</th><th width="166">Type</th><th>Description</th></tr></thead><tbody><tr><td>secondsPerLiquidityInsideInitialX128</td><td><code>uint160</code></td><td>secondsPerLiquidity represented as a UQ32.128.</td></tr><tr><td>liquidity</td><td><code>bytes32</code></td><td>The amount of liquidity in the NFT as of the last time the rewards were computed.</td></tr></tbody></table>

#### getRewardInfo

```solidity
function getRewardInfo(IncentiveKey memory key, uint256 tokenId)
    external
    view
    override
    returns (uint256 reward, uint160 secondsInsideX128)
```

Calculates the reward amount that will be received for the given stake.

<table><thead><tr><th width="192.5">Parameters</th><th width="166">Type</th><th>Description</th></tr></thead><tbody><tr><td>key</td><td><code>IncentiveKey</code></td><td>The ID of the incentive.</td></tr><tr><td>tokenId</td><td><code>uint256</code></td><td>The token ID of the staked liquidity NFT.</td></tr></tbody></table>

<table><thead><tr><th width="194.5">Return values</th><th width="166">Type</th><th>Description</th></tr></thead><tbody><tr><td>reward</td><td><code>uint256</code></td><td>The reward accrued to the NFT for the given incentive thus far.</td></tr><tr><td>secondsInsideX128</td><td><code>uint160</code></td><td>The seconds inside the tick range.</td></tr></tbody></table>
