# Wrapped SmartTokens

## wrappedSmartToken

[Git Source](https://github.com/RiskProtocol/core-protocol/blob/d59ee719f0b8aa5daeb239f6468bda6d3a1b56be/contracts/vaults/wrapped/WrappedSmartToken.sol)

**Inherits:** UnbuttonToken, UUPSUpgradeable, OwnableUpgradeable, FlashloanSpecifics, BaseContract

### State Variables

#### sellingToken

```solidity
address private sellingToken;
```

#### isWrappedX

```solidity
bool private isWrappedX;
```

#### timeout

```solidity
uint256 private timeout;
```

#### SCALING\_FACTOR

```solidity
uint256 private constant SCALING_FACTOR = 10 ** 18;
```

#### orchestrator

```solidity
address private orchestrator;
```

#### premiumPercentage

```solidity
uint16 private premiumPercentage;
```

#### premiumDenominator

```solidity
uint16 private constant premiumDenominator = 10000;
```

#### signers

This is the signers address of RP api's that generate encoded params for rebalance

```solidity
mapping(address => bool) private signers;
```

#### currentDiscountRates

```solidity
DiscountRates private currentDiscountRates;
```

#### \_activeLoan

```solidity
LoanType private _activeLoan;
```

### Functions

#### onlyOrchestrator

```solidity
modifier onlyOrchestrator();
```

#### CustomNonReentrant

```solidity
modifier CustomNonReentrant(LoanType loanType);
```

#### constructor

**Note:** oz-upgrades-unsafe-allow: constructor

```solidity
constructor();
```

#### riskInitialize

```solidity
function riskInitialize(
    address underlying_,
    address sellingToken_,
    string memory name_,
    string memory symbol_,
    uint256 initialRate,
    bool isWrappedX_,
    address owner_,
    address signer,
    uint256 timeout_,
    address sanctionsContract_,
    address orchestrator_
) public initializer;
```

#### initialize

```solidity
function initialize(address underlying_, string memory name_, string memory symbol_, uint256 initialRate)
    public
    pure
    override;
```

#### \_authorizeUpgrade

```solidity
function _authorizeUpgrade(address newImplementation) internal override onlyOwner;
```

#### flashLoanAlt

Allows user to take flashloans from the wrapper

*This function is guarded by the `nonReentrant` modifiers. we offer unwanted tokens (sellingToken) in exchange of underlying tokens*

```solidity
function flashLoanAlt(
    address receiver,
    uint256 amount,
    bytes memory encodedData,
    bytes memory signature,
    bytes memory params
)
    external
    CustomNonReentrant(LoanType.FLASHLOANALT)
    stopFlashLoan
    onlyNotSanctioned(receiver)
    onlyNotSanctioned(_msgSender());
```

**Parameters**

| Name          | Type      | Description                                                                       |
| ------------- | --------- | --------------------------------------------------------------------------------- |
| `receiver`    | `address` | The address of the receiver.                                                      |
| `amount`      | `uint256` | The amount of underlying assets to flashloan.                                     |
| `encodedData` | `bytes`   |                                                                                   |
| `signature`   | `bytes`   |                                                                                   |
| `params`      | `bytes`   | The parameters for the flashloan. Used by the receiver contract(Aave's interface) |

#### flashLoan

Allows user to take flashloans from the wrapper (Vault/POOL)

*This function is guarded by the `nonReentrant` and `stopFlashLoan` modifiers. It makes use of AAVE's flashloan interface to provide backwards compatibility for ease of use*

```solidity
function flashLoan(address receiver, uint256 amount, bytes memory params)
    external
    CustomNonReentrant(LoanType.FLASHLOAN)
    stopFlashLoan
    onlyNotSanctioned(receiver)
    onlyNotSanctioned(_msgSender());
```

**Parameters**

| Name       | Type      | Description                                                                       |
| ---------- | --------- | --------------------------------------------------------------------------------- |
| `receiver` | `address` | The address of the receiver.                                                      |
| `amount`   | `uint256` | The amount of underlying assets to flashloan.                                     |
| `params`   | `bytes`   | The parameters for the flashloan. Used by the receiver contract(Aave's interface) |

#### setTimeout

```solidity
function setTimeout(uint256 timeout_) external onlyOwner;
```

#### discountRateSetter

```solidity
function discountRateSetter(uint256 startTime, uint256 endTime, uint256 discountMin, uint256 discountMax)
    private
    returns (bool);
```

#### setDiscountRateOrchestrator

```solidity
function setDiscountRateOrchestrator(uint256 startTime, uint256 endTime, uint256 discountMin, uint256 discountMax)
    external
    onlyOrchestrator
    returns (bool);
```

#### setDiscountRate

```solidity
function setDiscountRate(uint256 startTime, uint256 endTime, uint256 discountMin, uint256 discountMax)
    external
    onlyOwner
    returns (bool);
```

#### setSigners

```solidity
function setSigners(address signer, bool status) external onlyOwner;
```

#### setPremiumPercentage

```solidity
function setPremiumPercentage(uint16 percentage) external onlyOwner;
```

#### setOrchestator

```solidity
function setOrchestator(address orchestrator_) external onlyOwner;
```

#### getFlashloanPremium

```solidity
function getFlashloanPremium() public view returns (uint16);
```

#### getIsWrappedX

```solidity
function getIsWrappedX() external view returns (bool);
```

#### getTimeout

```solidity
function getTimeout() external view returns (uint256);
```

#### getDiscountRate

```solidity
function getDiscountRate() external view returns (DiscountRates memory);
```

#### getSigners

```solidity
function getSigners(address signer) external view returns (bool);
```

#### calculateUserShare

```solidity
function calculateUserShare() private view returns (uint256);
```

#### refundUnwantedTokens

```solidity
function refundUnwantedTokens(address user) private;
```

#### getConversionRate

```solidity
function getConversionRate(PriceFeed memory priceFeed, uint256 t1, uint256 t2, uint256 x1, uint256 x2)
    private
    view
    returns (uint256, uint256);
```

#### getOrchestrator

```solidity
function getOrchestrator() external view returns (address);
```

#### verifyAndDecode

Verifies the provided signature and decodes the encoded data into `ScheduledRebalance` struct.

*It recovers the address from the Ethereum signed message hash and the provided `signature`. If the recovered address doesn't match the `signersAddress`, it reverts the transaction. If the signature is valid, it decodes the `encodedData` into a `ScheduledRebalance` struct and returns it.*

```solidity
function verifyAndDecode(bytes memory signature, bytes memory encodedData) private view returns (PriceFeed memory);
```

**Parameters**

| Name          | Type    | Description                                                |
| ------------- | ------- | ---------------------------------------------------------- |
| `signature`   | `bytes` | The signature to be verified.                              |
| `encodedData` | `bytes` | The data to be decoded into a `ScheduledRebalance` struct. |

**Returns**

| Name     | Type        | Description                                                     |
| -------- | ----------- | --------------------------------------------------------------- |
| `<none>` | `PriceFeed` | data A `ScheduledRebalance` struct containing the decoded data. |

#### burn

Burns wrapper tokens from {msg.sender} and transfers the underlying tokens back.

```solidity
function burn(uint256 amount) public override returns (uint256);
```

**Parameters**

| Name     | Type      | Description                           |
| -------- | --------- | ------------------------------------- |
| `amount` | `uint256` | The amount of wrapper tokens to burn. |

**Returns**

| Name     | Type      | Description                                |
| -------- | --------- | ------------------------------------------ |
| `<none>` | `uint256` | The amount of underlying tokens withdrawn. |

#### burnTo

Burns wrapper tokens from {msg.sender} and transfers the underlying tokens to the specified beneficiary.

```solidity
function burnTo(address to, uint256 amount) public override returns (uint256);
```

**Parameters**

| Name     | Type      | Description                           |
| -------- | --------- | ------------------------------------- |
| `to`     | `address` | The beneficiary account.              |
| `amount` | `uint256` | The amount of wrapper tokens to burn. |

**Returns**

| Name     | Type      | Description                                |
| -------- | --------- | ------------------------------------------ |
| `<none>` | `uint256` | The amount of underlying tokens withdrawn. |

#### burnAll

Burns all wrapper tokens from {msg.sender} and transfers the underlying tokens back.

```solidity
function burnAll() public override returns (uint256);
```

**Returns**

| Name     | Type      | Description                                |
| -------- | --------- | ------------------------------------------ |
| `<none>` | `uint256` | The amount of underlying tokens withdrawn. |

#### burnAllTo

Burns all wrapper tokens from {msg.sender} and transfers the underlying tokens back.

```solidity
function burnAllTo(address to) public override returns (uint256);
```

**Parameters**

| Name | Type      | Description              |
| ---- | --------- | ------------------------ |
| `to` | `address` | The beneficiary account. |

**Returns**

| Name     | Type      | Description                                |
| -------- | --------- | ------------------------------------------ |
| `<none>` | `uint256` | The amount of underlying tokens withdrawn. |

#### withdraw

Burns wrapper tokens from {msg.sender} and transfers the underlying tokens back.

```solidity
function withdraw(uint256 uAmount) public override returns (uint256);
```

**Parameters**

| Name      | Type      | Description                                  |
| --------- | --------- | -------------------------------------------- |
| `uAmount` | `uint256` | The amount of underlying tokens to withdraw. |

**Returns**

| Name     | Type      | Description                         |
| -------- | --------- | ----------------------------------- |
| `<none>` | `uint256` | The amount of wrapper tokens burnt. |

#### withdrawTo

Burns wrapper tokens from {msg.sender} and transfers the underlying tokens back to the specified beneficiary.

```solidity
function withdrawTo(address to, uint256 uAmount) public override returns (uint256);
```

**Parameters**

| Name      | Type      | Description                                  |
| --------- | --------- | -------------------------------------------- |
| `to`      | `address` | The beneficiary account.                     |
| `uAmount` | `uint256` | The amount of underlying tokens to withdraw. |

**Returns**

| Name     | Type      | Description                         |
| -------- | --------- | ----------------------------------- |
| `<none>` | `uint256` | The amount of wrapper tokens burnt. |

#### withdrawAll

Burns all wrapper tokens from {msg.sender} and transfers the underlying tokens back.

```solidity
function withdrawAll() public override returns (uint256);
```

**Returns**

| Name     | Type      | Description                         |
| -------- | --------- | ----------------------------------- |
| `<none>` | `uint256` | The amount of wrapper tokens burnt. |

#### withdrawAllTo

Burns all wrapper tokens from {msg.sender} and transfers the underlying tokens back.

```solidity
function withdrawAllTo(address to) public override returns (uint256);
```

**Parameters**

| Name | Type      | Description              |
| ---- | --------- | ------------------------ |
| `to` | `address` | The beneficiary account. |

**Returns**

| Name     | Type      | Description                         |
| -------- | --------- | ----------------------------------- |
| `<none>` | `uint256` | The amount of wrapper tokens burnt. |

### Errors

#### WrappedSmartToken\_\_Not\_Implemented

```solidity
error WrappedSmartToken__Not_Implemented();
```

#### WrappedSmartToken\_\_PriceFeedOutdated

```solidity
error WrappedSmartToken__PriceFeedOutdated();
```

#### WrappedSmartToken\_\_InvalidSigner

```solidity
error WrappedSmartToken__InvalidSigner();
```

#### WrappedSmartToken\_\_InvalidDiscount

```solidity
error WrappedSmartToken__InvalidDiscount();
```

#### WrappedSmartToken\_\_InvalidOrchestrator

```solidity
error WrappedSmartToken__InvalidOrchestrator();
```

#### WrappedSmartToken\_\_ReEntrantCall

```solidity
error WrappedSmartToken__ReEntrantCall();
```

### Structs

#### PriceFeed

```solidity
struct PriceFeed {
    uint256 smartTokenXValue;
    uint256 smartTokenYValue;
    uint256 timestamp;
}
```

#### DiscountRates

```solidity
struct DiscountRates {
    uint256 startTime;
    uint256 endTime;
    uint256 discountMin;
    uint256 discountMax;
}
```

### Enums

#### LoanType

```solidity
enum LoanType {
    NONE,
    FLASHLOAN,
    FLASHLOANALT
}
```
