# LERC20

**LERC20** is an extension of standard [**ERC20**](https://ethereum.org/en/developers/docs/standards/tokens/erc-20/) that enables all the lossless features. It has the same methods and interface as a **ERC20** with only a few extra methods, modifiers and variables.

**LERC20** code can be found here:

{% embed url="<https://github.com/Lossless-Cash/lossless-v4/blob/master/contracts/utils/first-version/LERC20.sol>" %}

**LERC20Burnable:**

{% embed url="<https://github.com/Lossless-Cash/lossless-v4/blob/master/contracts/LERC20Burnable.sol>" %}

**LERC20Mintable:**

{% embed url="<https://github.com/Lossless-Cash/lossless-v4/blob/master/contracts/LERC20Mintable.sol>" %}

**LERC20MintableBurnable:**

{% embed url="<https://github.com/Lossless-Cash/lossless-v4/blob/master/contracts/LERC20MintableBurnable.sol>" %}

### Variables

If you would look at the **LERC20** you will see that it has these extra variables:

* `recoveryAdmin`
* `recoveryAdminCanditate`
* `recoveryAdminKeyHash`
* `admin`
* `timelockPeriod`
* `losslessTurnOffTimestamp`
* `isLosslessTurnOffProposed`
* `isLosslessOn`
* `lossless`

Below we explain each of these variables one by one:

#### recoveryAdmin

This is a super admin of token. This wallet is able to change the regular admin wallet and propose turning off lossless functionality in the token. This wallet is the most powerful admin wallet in the whole lossless protocol and we recommend using a secure and time tested multisig (like [Gnosis Safe](https://gnosis-safe.io/)) for it. This variable is set in the constructor and can later be changed using `transferRecoveryAdminOwnership`  function.

#### recoveryAdminCanditate

This address is a wallet that is proposed to take the recoveryAdmin's place. It is set in `transferRecoveryAdminOwnership` function.

#### recoveryAdminKeyHash

This is a string that is set when proposing a new recoveryAdmin. This key has ensures that only the wallet owner who knows the original string for this hash can accept the ownership. This means that even if someone by mistake enters incorrect recoveryAdmin's wallet that wallet won't be able to accept the ownership because it does not know the key. This variables is set in `transferRecoveryAdminOwnership` function.

#### admin

This address is a wallet of the token admin. This token admin wallet has access to some particular lossless features, like participating in lossless decision making body and using other the lossless functionality like vault protection. You could think of this wallet as wallet that allows the project owners to interact with the lossless protocol while recoveryAdmin is backup wallet that allows changing this admin wallet in case it gets compromised. Admin wallet is a powerful admin wallet and we recommend using a secure and time tested multisig (like [Gnosis Safe](https://gnosis-safe.io/)) for it. This variable is initial set in the constructor but later can be changed using `setLosslessAdmin` function.

#### timelockPeriod

This period is a time period in seconds that is required to pass after the lossless turn off decision is proposed and before it can be executed. This basically means that in order for the projects owners to turn off lossless they have to wait for this time period to complete. This timelock communicates about the plans to turn lossless off on chain. This gives heads up both the project's community and lossless finders. This variables is set in the constructor when deploying token smart contract and **cannot be changed later**.

#### losslessTurnOffTimestamp

This timestamp indicates when the lossless functionality can be turned off in the particular token. Before it passes lossless functionality cannot be turned off. It is set when the lossless turn off is proposed by the recoveryAdmin in the `proposeLosslessTurnOff` function. This variable is a product of `block.timestamp + timelockPeriod`.

#### isLosslessTurnOffProposed

This flag indicates if the proposal to turn lossless functionality off was initiated. It is set in the `proposeLosslessTurnOff` function.

#### isLosslessOn

This flag indicates if the lossless functionality is enabled for the particular token. This variable is set in `executeLosslessTurnOff` function.

#### lossless

This address is an address of the lossless controller contract. Lossless controller contract is a contract which implements all the lossless features. There is single controller for each of the blockchains and all the tokens on one particular blockchain should be using the same controller address.

### Modifiers

Lossless functionality is implemented by using modifiers on regular ERC20 functions. For example in LERC20 `transfer` function has `lssTransfer` modifier. There's a unique modifier for each public ERC20 function. This is the complete modifiers list that enables lossless functionality for the ERC20 token:

* `lssAprove`
* `lssTransfer`
* `lssTransferFrom`
* `lssIncreaseAllowance`
* `lssDecreaseAllowance`
* `onlyRecoveryAdmin`

All the modifiers starting with `lss` prefix use the same pattern:

1. Check if lossless is enabled in the token (`isLosslessOn == true`).
2. If lossless is enabled:
   1. Call lossless controller and forward all the arguments to it.
   2. Run the original function call.
   3. Call lossless controller once more and forward all the arguments to it.
3. If lossless is disabled:
   1. Just call the original function without any call to lossless controller.

Lossless controller is called before and after each public ERC20 method is executed. It allows it to run all the necessary validations and any other logic that checks if the function call can proceed.

Lossless controller has specific methods for each and every LERC20 modifier. For example `lssTransfer` calls `lossless.beforeTransfer` before executing the original function call and then later on call `lossless.afterTransfer` after executing the original function call. However, none of these methods are called when the lossless is turned off for the particular token.

#### onlyRecoveryAdmin

This modifier is an access control check that validate if the msg.sender is the `recoveryAdmin`. It is used in these privileged methods: `setLosslessAdmin, transferRecoveryAdminOwnership, proposeLosslessTurnOff, executeLosslessTurnOn.`

### `Functions`

#### getAdmin

```solidity
function getAdmin() external view returns (address)
```

Return Values:

Returns `admin` of the token.

#### transferOutBlacklistedFunds

```solidity
function transferOutBlacklistedFunds(address[] calldata from) external
```

This is a core method of LERC20. It allows lossless protocol to transfer the tokens of the blacklisted address. After the incident is reported and the report is validated by the lossless decision making body the tokens that were stolen can be first transferred to lossless protocol and them returned to back to the project that suffered the incident.&#x20;

Parameters:

| Name   | Type       | Description                                                                                           |
| ------ | ---------- | ----------------------------------------------------------------------------------------------------- |
| `from` | address\[] | A list of addresses that are blacklisted and whose tokens should be returned back after the incident. |

####

#### setLosslessAdmin

```solidity
function setLosslessAdmin(address newAdmin) public onlyRecoveryAdmin
```

Set `admin` wallet address.

Parameters:

| Name       | Type    | Description               |
| ---------- | ------- | ------------------------- |
| `newAdmin` | address | Address of the new admin. |

####

#### transferRecoveryAdminOwnership

```solidity
function transferRecoveryAdminOwnership(
     address candidate,
     bytes32 keyHash
) public onlyRecoveryAdmin
```

Sets the `recoveryAdminCanditate` and `recoveryAdminKeyHash.` This is the first step in transferring the ownership of the `recoveryAdmin`

Parameters:

| Name        | Type    | Description                                                                               |
| ----------- | ------- | ----------------------------------------------------------------------------------------- |
| `candidate` | address | Address of the new recovery admin.                                                        |
| `keyHash`   | bytes32 | A hash of a key that the new recovery admin should know in order to accept the ownership. |

####

#### acceptRecoveryAdminOwnership

```solidity
function acceptRecoveryAdminOwnership(bytes memory key) external 
```

Allows `recoveryAdminCanditate` to accept the ownership of `recoveryAdmin` by providing a `key` that has a hash equal to `recoveryAdminKeyHash`.

Parameters:

| Name  | Type  | Description                                                   |
| ----- | ----- | ------------------------------------------------------------- |
| `key` | bytes | `key` that has to have a hash equal to `recoveryAdminKeyHash` |

####

#### proposeLosslessTurnOff

```solidity
function proposeLosslessTurnOff() public onlyRecoveryAdmin
```

Initialises lossless functionality turn off. Sets `losslessTurnOffTimestamp` and `isLosslessTurnOffProposed`.

#### executeLosslessTurnOff

```solidity
function executeLosslessTurnOff() public onlyRecoveryAdmin
```

Turns off the lossless functionality in particular token. Lossless can only turned of after the `proposeLosslessTurnOff` is called first and the `losslessTurnOffTimestamp` has passed.

#### executeLosslessTurnOn

```solidity
function executeLosslessTurnOn() public onlyRecoveryAdmin
```

Turns lossless functionality back on. No timelock is required, lossless gets turned of immediately after calling this function.


---

# 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://docs.lossless.io/protocol/technical-reference/lerc20.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.
