LERC20 is an extension of standard ERC20 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:





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:


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) for it. This variable is set in the constructor and can later be changed using transferRecoveryAdminOwnership function.


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


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.


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) for it. This variable is initial set in the constructor but later can be changed using setLosslessAdmin function.


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.


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.


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


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


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.


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.


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.



function getAdmin() external view returns (address)

Return Values:

Returns admin of the token.


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.





A list of addresses that are blacklisted and whose tokens should be returned back after the incident.


function setLosslessAdmin(address newAdmin) public onlyRecoveryAdmin

Set admin wallet address.





Address of the new admin.


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





Address of the new recovery admin.



A hash of a key that the new recovery admin should know in order to accept the ownership.


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.





key that has to have a hash equal to recoveryAdminKeyHash


function proposeLosslessTurnOff() public onlyRecoveryAdmin

Initialises lossless functionality turn off. Sets losslessTurnOffTimestamp and isLosslessTurnOffProposed.


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.


function executeLosslessTurnOn() public onlyRecoveryAdmin

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

Last updated