# SDL Pool

The `SDLPool` allows users to stake and/or lock SDL tokens and receive reSDL (Reward Escrowed SDL) in return. SDL stakers will receive a portion of protocol rewards proportional to the amount of reSDL they hold. They will also receieve priority staking access in the `PriorityPool` over non reSDL holders. A user's reSDL balance is represented by one or multiple NFTs which are minted when SDL is staked/locked in the pool.

If a user stakes but does not lock their SDL, they will receive an NFT representing reSDL at a 1:1 ratio to the SDL they staked. If a user locks their SDL, they will receive an additional boosted amount of reSDL depending on the duration they have chosen to lock for, resulting in a ratio greater than 1:1. The calculation for the amount of boost received for a specific amount of SDL and locking duration is handled by the `LinearBoostController`.

If an reSDL position is not locked, the underlying SDL can be withdrawn at any time. If a position is locked, the withdrawal period must be initiated before SDL can be withdrawn. The withdrawal period can only be initiated after at least half of the total locking duration has elapsed and the withdrawal period itself will have a duration of exactly half the total locking duration. For the duration of the withdrawal period, the boost amount for the position will be set to 0 and only after this period has elapsed, the underlying SDL can be withdrawn.

A user can hold any number of reSDL NFTs and NFTs are transferrable in all states but by transferring an NFT, the ownership of the underlying SDL is also transferred.

## ERC721 Functions

All standard IERC721 and IERC721Metadata functions are implemented for `SDLPool`

## View Functions

### name

Returns the name of the staking derivative token.

```solidity
function name() public view returns (string)
```

#### Return Values

| Name | Type   | Description       |
| ---- | ------ | ----------------- |
| name | string | Name of the token |

### symbol

Returns the symbol of the staking derivative token.

```solidity
function symbol() public view returns (string)
```

#### Return Values

| Name   | Type   | Description         |
| ------ | ------ | ------------------- |
| symbol | string | Symbol of the token |

### sdlToken

Returns the SDL token contract address.

```solidity
function sdlToken() public view returns (address)
```

#### Return Values

| Name     | Type    | Description       |
| -------- | ------- | ----------------- |
| sdlToken | address | SDL token address |

### boostController

Returns the boost controller contract address.

```solidity
function boostController() public view returns (address)
```

#### Return Values

| Name            | Type    | Description              |
| --------------- | ------- | ------------------------ |
| boostController | address | Boost controller address |

### lastLockId

Returns the last lock ID created.

```solidity
function lastLockId() public view returns (uint256)
```

#### Return Values

| Name       | Type    | Description  |
| ---------- | ------- | ------------ |
| lastLockId | uint256 | Last lock ID |

### totalEffectiveBalance

Returns the total effective balance (including boosts) staked in the pool.

```solidity
function totalEffectiveBalance() public view returns (uint256)
```

#### Return Values

| Name                  | Type    | Description             |
| --------------------- | ------- | ----------------------- |
| totalEffectiveBalance | uint256 | Total effective balance |

### delegatorPool

Returns the address of the delegator pool contract.

```solidity
function delegatorPool() public view returns (address)
```

#### Return Values

| Name          | Type    | Description            |
| ------------- | ------- | ---------------------- |
| delegatorPool | address | Delegator pool address |

### baseURI

Returns the base URI for all tokens.

```solidity
function baseURI() public view returns (string)
```

#### Return Values

| Name    | Type   | Description |
| ------- | ------ | ----------- |
| baseURI | string | Base URI    |

### effectiveBalanceOf

Returns the effective stake balance of an account, including boosts.

```solidity
function effectiveBalanceOf(address _account) external view returns (uint256)
```

| Name      | Type    | Description     |
| --------- | ------- | --------------- |
| \_account | address | Account address |

#### Return Values

| Name             | Type    | Description             |
| ---------------- | ------- | ----------------------- |
| effectiveBalance | uint256 | Effective stake balance |

### balanceOf

Returns the number of locks owned by an account.

```solidity
function balanceOf(address _account) public view returns (uint256)
```

| Name      | Type    | Description     |
| --------- | ------- | --------------- |
| \_account | address | Account address |

#### Return Values

| Name    | Type    | Description     |
| ------- | ------- | --------------- |
| balance | uint256 | Number of locks |

### ownerOf

Returns the owner of a lock.

```solidity
function ownerOf(uint256 _lockId) public view returns (address)
```

| Name     | Type    | Description |
| -------- | ------- | ----------- |
| \_lockId | uint256 | Lock ID     |

#### Return Values

| Name  | Type    | Description |
| ----- | ------- | ----------- |
| owner | address | Lock owner  |

### getLocks

Returns the list of locks for the given lock IDs.

```solidity
function getLocks(uint256[] calldata _lockIds) external view returns (Lock[] memory)
```

| Name      | Type       | Description      |
| --------- | ---------- | ---------------- |
| \_lockIds | uint256\[] | List of lock IDs |

#### Return Values

| Name  | Type    | Description   |
| ----- | ------- | ------------- |
| locks | Lock\[] | List of locks |

### getLockIdsByOwner

Returns a list of lock IDs owned by an account.

```solidity
function getLockIdsByOwner(address _owner) external view returns (uint256[] memory)
```

| Name    | Type    | Description |
| ------- | ------- | ----------- |
| \_owner | address | Account     |

#### Return Values

| Name    | Type       | Description      |
| ------- | ---------- | ---------------- |
| lockIds | uint256\[] | List of lock IDs |

### staked

Returns an account's staked amount for use by reward pools.

```solidity
function staked(address _account) external view returns (uint256)
```

| Name      | Type    | Description     |
| --------- | ------- | --------------- |
| \_account | address | Account address |

#### Return Values

| Name   | Type    | Description   |
| ------ | ------- | ------------- |
| staked | uint256 | Staked amount |

### totalStaked

Returns the total staked amount for use by reward pools.

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

#### Return Values

| Name        | Type    | Description         |
| ----------- | ------- | ------------------- |
| totalStaked | uint256 | Total staked amount |

### supportedTokens

Returns a list of supported tokens.

```solidity
function supportedTokens() external view returns (address[] memory)
```

#### Return Values

| Name   | Type       | Description              |
| ------ | ---------- | ------------------------ |
| tokens | address\[] | List of supported tokens |

### isTokenSupported

Returns true/false for whether a given token is supported.

```solidity
function isTokenSupported(address _token) public view returns (bool)
```

| Name    | Type    | Description   |
| ------- | ------- | ------------- |
| \_token | address | Token address |

#### Return Values

| Name      | Type | Description        |
| --------- | ---- | ------------------ |
| supported | bool | Is token supported |

### tokenBalances

Returns balances of supported tokens within the controller.

```solidity
function tokenBalances() external view returns (address[] memory, uint256[] memory)
```

#### Return Values

| Name     | Type       | Description              |
| -------- | ---------- | ------------------------ |
| tokens   | address\[] | List of supported tokens |
| balances | uint256\[] | List of token balances   |

### withdrawableRewards

Returns a list of withdrawable rewards for an account.

```solidity
function withdrawableRewards(address _account) external view returns (uint256[] memory)
```

| Name      | Type    | Description     |
| --------- | ------- | --------------- |
| \_account | address | Account address |

#### Return Values

| Name    | Type       | Description                  |
| ------- | ---------- | ---------------------------- |
| rewards | uint256\[] | List of withdrawable rewards |

## Write Functions

### onTokenTransfer

ERC677 implementation to stake/lock SDL tokens or distribute rewards.

```solidity
function onTokenTransfer(address _sender, uint256 _value, bytes calldata _calldata) external
```

| Name       | Type    | Description                        |
| ---------- | ------- | ---------------------------------- |
| \_sender   | address | Sender address                     |
| \_value    | uint256 | Value transferred                  |
| \_calldata | bytes   | Encoded lockId and lockingDuration |

### extendLockDuration

Extends the locking duration of a lock.

```solidity
function extendLockDuration(uint256 _lockId, uint64 _lockingDuration) external
```

| Name              | Type    | Description          |
| ----------------- | ------- | -------------------- |
| \_lockId          | uint256 | Lock ID              |
| \_lockingDuration | uint64  | New locking duration |

### initiateUnlock

Initiates the unlock period for a lock.

```solidity
function initiateUnlock(uint256 _lockId) external
```

| Name     | Type    | Description |
| -------- | ------- | ----------- |
| \_lockId | uint256 | Lock ID     |

### withdraw

Withdraws unlocked SDL from a lock.

```solidity
function withdraw(uint256 _lockId, uint256 _amount) external
```

| Name     | Type    | Description        |
| -------- | ------- | ------------------ |
| \_lockId | uint256 | Lock ID            |
| \_amount | uint256 | Amount to withdraw |

### setBaseURI

Sets the base URI for all tokens.

```solidity
function setBaseURI(string calldata _baseURI) external
```

| Name      | Type   | Description |
| --------- | ------ | ----------- |
| \_baseURI | string | Base URI    |

### setBoostController

Sets the boost controller contract.

```solidity
function setBoostController(address _boostController) external
```

| Name              | Type    | Description      |
| ----------------- | ------- | ---------------- |
| \_boostController | address | Boost controller |

### migrate

Used by the delegator pool to migrate user stakes to this contract.

```solidity
function migrate(address _sender, uint256 _amount, uint64 _lockingDuration) external
```

| Name              | Type    | Description      |
| ----------------- | ------- | ---------------- |
| \_sender          | address | Owner of lock    |
| \_amount          | uint256 | Amount to stake  |
| \_lockingDuration | uint64  | Duration of lock |

### distributeTokens

Distributes token balances to their respective rewards pools.

```solidity
function distributeTokens(address[] memory _tokens) public
```

| Name     | Type       | Description             |
| -------- | ---------- | ----------------------- |
| \_tokens | address\[] | List of token addresses |

### distributeToken

Distributes a token balance to its respective rewards pool.

```solidity
function distributeToken(address _token) public
```

| Name    | Type    | Description   |
| ------- | ------- | ------------- |
| \_token | address | Token address |

### withdrawRewards

Withdraws an account's earned rewards for a list of tokens.

```solidity
function withdrawRewards(address[] memory _tokens) public
```

| Name     | Type       | Description             |
| -------- | ---------- | ----------------------- |
| \_tokens | address\[] | List of token addresses |

### addToken

Adds a new token and its rewards pool.

```solidity
function addToken(address _token, address _rewardsPool) public
```

| Name          | Type    | Description        |
| ------------- | ------- | ------------------ |
| \_token       | address | Token to add       |
| \_rewardsPool | address | Token rewards pool |

### removeToken

Removes a supported token.

```solidity
function removeToken(address _token) external
```

| Name    | Type    | Description   |
| ------- | ------- | ------------- |
| \_token | address | Token address |
