Lossless Controller V3

This contract is the gateway contract that connects LERC20 token contracts with all the lossless hack mitigation system.

Contract can be found here:

Hack Mitigation Repository

Variables

  • admin

  • pauseAdmin

  • recoveryAdmin

  • guardian

  • tokenProtections

  • Protections

  • Protection

  • losslessStaking

  • losslessReporting

  • losslessGovernance

  • tokenScopedLockedFunds

  • TokenLockedFunds

  • LocksQueue

  • ReceiveCheckpoint

  • HUNDRED

  • dexTranferThreshold

  • settlementTimeLock

  • dexList

  • whitelist

  • blacklist

  • tokenConfig

  • TokenConfig

admin

This address correspondes to the set Lossless Admin. Has different capabilities over the Lossless Environment.

pauseAdmin

This address has the access to pause and unpause controller contract.

recoveryAdmin

This is a super admin's address. This wallet is able to change the regular admin and pause admin. This address is the most powerful admin in the whole lossless protocol and we are using a secure and time tested multi-sig (Gnosis Safe) for it. This variable can be changed using transferRecoveryAdminOwnership function.

guardian

The address of the guardian smart contract. Guardian contract has access to control protection strategies on controller contract.

tokenProtections

This mapping saves info about every address that is protected. It has a flag that shows if the address is protected or not and also has strategy address so that if the address is protected the controller knows which of the protections strategies should be applied.

Protections

This structure contains a mapping of all the protected addresses related to a LERC20 token and the protection type for each address using the Protection structure.

Protection

This structure contains a boolean that determines if the vault protection is active and the protection strategy being used.

losslessStaking

The ILssStaking type refers to the Lossless Staking Interface, the variable itself contains the Smart Contract address of the Lossless Staking to allow interaction.

losslessReporting

The ILssReporting type refers to the Lossless Reporting Interface, the variable itself contains the Smart Contract address of the Lossless Reporting to allow interaction.

losslessGovernance

The ILssGovernance type refers to the Lossless Governance Interface, the variable itself contains the Smart Contract address of the Lossless Governance to allow interaction.

tokenScopedLockedFunds

This mapping contains all the information pertinent to the settlement period of an LERC20 token and the order that the received funds get queued and freed to be used per address by using the TokenLockedFunds structure.

TokenLockedFunds

The structure contains a mapping that refers an address to its queue of received and available funds. It uses the LocksQueue structure to save the details.

LocksQueue

The structure contains a mapping numbered by the checkpoints of which the funds were received and freed by using the ReceiveCheckpoint structure. Also it contains a uint256 that determines when was the last time that it was modified as well as two uint256 that determines the first and last item to check.

ReceiveCheckpoint

Contains the detail of each received transaction, being the amount queued and the timestamp when it was added to the queue.

HUNDRED

Used in order to calculate percentages. Constant value of 100.

dexTranferThreshold

It contains the amount of tokens to consider as a threshold over the unsettled tokens when transferring to a Decentralized exchange.

settlementTimeLock

It refers to the amount in time in seconds that it has to pass between the proposal of a settlement period change for a certain LERC20 token and the time of execution.

dexList

List containing all the set Decentralized exchanges addresses.

whitelist

List containing all the set Whitelisted addresses mainly being the Lossless Smart Contracts and environment.

blacklist

List containing all the set Blacklistedaddresses mainly being the correctly reported addresses.

tokenConfig

It associates an LERC20 token with a list of variables corresponding to their particular configuration and needed data via the TokenConfig structure.

TokenConfig

It contains a set of variables corresponding to certain configurations of a LERC20 token.

  • uint256 tokenLockTimeframe - Settlement Period of the tokens in seconds

  • uint256 proposedTokenLockTimeframe - Settlement period change proposal in seconds

  • uint256 changeSettlementTimelock - Settlement Timelock change proposal in seconds

  • uint256 emergencyMode - Timestamp of when the emergencyMode got active.

Modifiers

  • onlyLosslessAdmin()

  • onlyPauseAdmin()

  • onlyLosslessRecoveryAdmin()

  • onlyGuardian()

  • onlyLosslessEnv()

onlyLosslessAdmin()

This modifiers ensures that the wrapped method can only be executed by the Lossless Admin

onlyPauseAdmin()

This modifiers ensures that the wrapped method can only be executed by the Pause Admin

onlyLosslessRecoveryAdmin()

This modifiers ensures that the wrapped method can only be executed by the Recovery Admin

onlyGuardian()

This modifiers ensures that the wrapped method can only be executed by the Guardian

onlyLosslessEnv()

This modifier ensures that the wrapped method can only be executed by the Lossless Environment

Events

  • AdminChange(address indexed _newAdmin)

  • RecoveryAdminChange(address indexed _newAdmin);

  • PauseAdminChange(address indexed _newAdmin);

  • GuardianSet(address indexed _oldGuardian, address indexed _newGuardian);

  • NewProtectedAddress(ILERC20 indexed _token, address indexed _protectedAddress, address indexed _strategy);

  • RemovedProtectedAddress(ILERC20 indexed _token, address indexed _protectedAddress);

  • NewSettlementPeriodProposal(ILERC20 indexed _token, uint256 _seconds);

  • SettlementPeriodChange(ILERC20 indexed _token, uint256 _proposedTokenLockTimeframe);

  • NewSettlementTimelock(uint256 indexed _timelock);

  • NewDexThreshold(uint256 indexed _newThreshold);

  • NewDex(address indexed _dexAddress);

  • DexRemoval(address indexed _dexAddress);

  • NewWhitelistedAddress(address indexed _whitelistAdr);

  • WhitelistedAddressRemoval(address indexed _whitelistAdr);

  • NewBlacklistedAddress(address indexed _blacklistedAddres);

  • AccountBlacklistRemoval(address indexed _adr);

  • NewStakingContract(ILssStaking indexed _newAdr);

  • NewReportingContract(ILssReporting indexed _newAdr);

  • NewGovernanceContract(ILssGovernance indexed _newAdr);

  • EmergencyActive(ILERC20 indexed _token);

  • EmergencyDeactivation(ILERC20 indexed _token);

  • NewMint(ILERC20 indexed token, address indexed account, uint256 indexed amount);

  • NewMintLimit(ILERC20 indexed token, uint256 indexed limit);

  • NewMintPeriod(ILERC20 indexed token, uint256 indexed period);

  • NewBurn(ILERC20 indexed token, address indexed account, uint256 indexed amount);

  • NewBurnLimit(ILERC20 indexed token, uint256 indexed limit);

  • NewBurnPeriod(ILERC20 indexed token, uint256 indexed period);

  • NewExtraordinaryPeriod(uint256 indexed extraordinaryRetrievalProposalPeriod);

Functions

  • pause()

  • unpause()

  • getVersion()

  • setAdmin()

  • setRecoveryAdmin()

  • setPauseAdmin()

  • setDexTransferThreshold()

  • addToBlacklist()

  • resolvedNegatively()

  • activateEmergency()

  • deactivateEmergency()

  • getLockedAmount()

  • getAvailableAmount()

  • retrieveBlacklistedFunds()

  • setStakingContractAddress()

  • setReportingContractAddress()

  • setGovernanceContractAddress()

  • setDexList()

  • setWhitelist()

  • setSettlementTimeLock()

  • proposeNewSettlementPeriod()

  • executeNewSettlementPeriod()

  • beforeTransfer()

  • beforeTransferFrom()

  • beforeMint()

  • beforeApprove()

  • beforeBurn()

  • beforeIncreaseAllowance()

  • beforeDecreaseAllowance()

  • afterMint()

  • afterApprove()

  • afterBurn()

  • afterIncreaseAllowance()

  • afterDecreaseAllowance()

  • afterTransfer()

  • afterTransferFrom()

  • isAddressProtected()

  • getProtectedAddressStrategy()

  • setGuardian()

  • setProtectedAddress()

  • removeProtectedAddress()

pause

function pause() external onlyPauseAdmin

Sets the pause flag to true which in turn pauses some of the contracts functionality. Can be called only by the pauseAdmin.

unpause

function unpause() external onlyPauseAdmin

Sets the pause flag to false which in turn unpauses some of the contracts functionality. Can be called only by the pauseAdmin.

getVersion()

function getVersion() external pure returns (uint256)

This method returns the version of the smart contract.

setAdmin

function setAdmin(address newAdmin) external onlyLosslessRecoveryAdmin

Sets admin address. Can be called only by recoveryAdmin.

Parameters:

Name
Type
Description

newAdmin

address

New admin address.

setRecoveryAdmin

function setRecoveryAdmin(address newRecoveryAdmin) external onlyLosslessRecoveryAdmin

Sets recoveryAdmin address. Can be called only by recoveryAdmin.

Parameters:

Name
Type
Description

newRecoveryAdmin

address

New recovery admin address.

setPauseAdmin

function setPauseAdmin(address newPauseAdmin) external onlyLosslessRecoveryAdmin

Sets pauseAdmin address. Can be called only by recoveryAdmin.

Parameters:

Name
Type
Description

newPauseAdmin

address

New pause admin address.

setDexTransferThreshold()

function setDexTransferThreshold(uint256 _newThreshold) override public onlyLosslessAdmin

Sets the transfer threshold for Dexes. Can be called by admin

Name
Type
Description

_newThreshold

uint256

New threshold amount.

addToBlacklist()

function addToBlacklist(address _adr) override public onlyLosslessEnv

This functions adds an address to the Blacklist. It’s called by losslessReporting

Name
Type
Description

_adr

address

Address to blacklist.

resolvedNegatively()

function resolvedNegatively(address _adr) override public onlyLosslessEnv

This functions removes an address to the Blacklist. It’s called by losslessGovernance Smart Contract when a report gets solved negatively.

Name
Type
Description

_adr

address

Address to remove from blacklist.

activateEmergency()

function activateEmergency(ILERC20 _token) override external onlyLosslessEnv

This function activates the emergency mode. It is called by the losslessReporting Smart Contract when generating a report.

When a report gets generated for a token, it enters an emergency state globally.

The emergency period will be active for one settlement period.

During this time users can only transfer settled tokens

Name
Type
Description

_token

ILERC20

Token address to activate emergency

deactivateEmergency()

function deactivateEmergency(ILERC20 _token) override external onlyLosslessEnv

This function activates the emergency mode. Called by losslessGovernance

Name
Type
Description

_token

ILERC20

Token address to deactivate emergency

getLockedAmount()

function getLockedAmount(ILERC20 _token, address _adr) override external onlyLosslessEnv

This function will return the non-settled tokens amount of the address.

Name
Type
Description

_token

ILERC20

Token address to deactivate emergency

_adr

address

Address to remove from blacklist

getAvailableAmount()

function _getAvailableAmount(ILERC20 _token, address account) private returns (uint256 amount)

This function will calculate the available amount that an address has to transfer.

Name
Type
Description

_token

ILERC20

Token address to deactivate emergency

_adr

address

Address to remove from blacklist

retrieveBlacklistedFunds()

function retrieveBlacklistedFunds(address[] calldata _addresses, ILERC20 _token, uint256 _reportId) override public onlyLosslessEnv returns(uint256)

This function retrieves the funds of the reported account. It is called from the Lossless Governance Smart Contract when the report gets solved positively.

Name
Type
Description

_addresses

Address array

Array of addresses to retrieve funds from

_token

ILERC20

Token address to deactivate emergency

_reportId

uint256

ID of the report

setStakingContractAddress()

function setStakingContractAddress(ILssStaking _adr) override public onlyLosslessAdmin

Sets the Lossless Staking Smart Contract Address for interaction. Called by admin

Name
Type
Description

_adr

ILssStaking

Address of the staking smart contract

setReportingContractAddress()

function setReportingContractAddress(ILssReporting _adr) override public onlyLosslessAdmin

Sets the Lossless Reporting Smart Contract Address for interaction. Called by admin

Name
Type
Description

_adr

ILssReporting

Address of the Reporting smart contract

setGovernanceContractAddress()

function setGovernanceContractAddress(ILssGovernance _adr) override public onlyLosslessAdmin

Sets the Lossless Governance Smart Contract Address for interaction. Called by admin

Name
Type
Description

_adr

ILssGovernance

Address of the Governance smart contract

setDexList()

function setDexList(address[] calldata _dexList, bool _value) override public onlyLosslessAdmin

If list is provide together with value true all addresses from the list should be included in the DEX list.

If list is provided together with value false all addresses from the list should not be included in the DEX list.

DEX list plays important part in the settlement period functionality.

Called by admin

Name
Type
Description

_dexList

Address array

Array of addresses to add to the dex list

_value

bool

Add or remove from Dex List

setWhitelist()

function setWhitelist(address[] calldata _addrList, bool _value) override public onlyLosslessAdmin

If list is provide together with value true all addresses from the list should be included in the whitelist list.

If list is provided together with value false all addresses from the list should not be included in the whitelist list.

Whitelisted addresses cannot be reporter and are entitled to some other benefits.

Called by admin

Name
Type
Description

_addrList

Address array

Array of addresses to add to the whitelist

_value

bool

Add or remove from Dex List

setSettlementTimeLock()

function setSettlementTimeLock(uint256 _newTimelock) override public onlyLosslessAdmin

Provided value is used to set settlement timelock. This timelock is used when Token Admin wants to change the settlement period changes.

Called by admin

Name
Type
Description

_newTimelock

uin256

New settlement Timelock

proposeNewSettlementPeriod()

function proposeNewSettlementPeriod(ILERC20 _token, uint256 _seconds) override public onlyTokenAdmin(_token)
Name
Type
Description

_token

ILERC20

Token address to create a proposal

_seconds

uin256

New proposed settlement period

Called by LERC20 admins

First provided value defines for which token these setting should be applied.

Period time is used by the settlement period functionality.

If period time is 0 settlement period is off and no rules should be executed.

This proposal is set and can be executed after settlement timelock is over. Settlement timelock start after the proposal is proposed.

  • Tokens Settlement

  1. Tokens Settlement Feature enables Lossless Protocol to stop hacks that both steal the tokens and sell them on a DEX in a single transaction.

  2. Tokens Settlement Feature can be enabled and disabled for each token separately by the token admin.

  3. Tokens Settlement Feature requires token admin to set settlement period variable.

  4. Tokens Settlement Feature works in two different ways when emergency mode is on and off.

  5. Tokens settlement feature works like this:

    • Tokens owned by any address are divided into to type of tokens:

      • settled tokens

      • unsettled tokens

    • Transferring of settled tokens is not impacted in any way. Transferring settled tokens is the same as transferring any standard ERC20 token - it’s permissionless and has no checks. (Except those implement by Lossless Vault and Treasury Protection Protocol).

    • Transferring of unsettled tokens however has a ruleset that defines when, where and how many of these tokens can be transferred.

    • When emergency mode is off (which is the case most of the time)

      • If unsettled tokens are being transferred to a decentralised exchange or any other address that is in dex list, these rules apply:

      • If amount of unsettled tokens being transferred to an address that is in dex list is below or equal to dex threshold transaction is allowed to go through.

      • If amount of unsettled tokens being transferred to an address that is in dex list is above dex threshold transaction fails.

    • If unsettled tokens are being transferred to a address that is in not in dex list, these rules apply:

      1. If this is the first transfer of unsettled tokens per settlement period transaction is allowed to go through.

      2. If this is not the first transfer of unsettled tokens per settlement period transaction fails.

    • When emergency mode is on:

      • None of the unsettled tokens can be transferred. No matter if the receiver is in dex list or not. No matter if amount of tokens being transferred is above or above dex threshold.

  • Emergency mode

  1. Emergency mode is boolean flag that can either be on or off.

  2. It is scoped in a particular token, meaning that while emergency mode is turned on for one token it could be turned off for another token.

  3. It gets turned on initial report is submitted by the finder.

  4. While it is on, Tokens Settlement Feature works in a different way that it usually does (check that part of documentation for the specifics)

  5. Emergency mode should be turned off after one settlement period after the initial report fast submitted.

executeNewSettlementPeriod()

function executeNewSettlementPeriod(ILERC20 _token) override public onlyTokenAdmin(_token)

This activates the initially proposed new settlement period values. Called by LERC20 admin

Name
Type
Description

_token

ILERC20

Token address to execute a proposal

beforeTransfer()

function beforeTransfer(address _sender, address _recipient, uint256 _amount) override external

If address is protected, transfer validation rules have to be run inside the strategy. Also applies all restrictions for blacklisted addresses and settlement periods.

Name
Type
Description

sender

address

Sender's address.

recipient

address

Recipient's address.

amount

uint256

Amount of tokens being transferred.

beforeTransferFrom()

function beforeTransfer(address _sender, address _recipient, uint256 _amount) override external

If address is protected, transfer validation rules have to be run inside the strategy. Also applies all restrictions for blacklisted addresses and settlement periods.

Name
Type
Description

msgSender

address

Address that triggered transfer from sender's address.

sender

address

Sender's address.

recipient

address

Recipient's address.

amount

uint256

Amount of tokens being transferred.

beforeMint()

Placeholder for future logic.

beforeApprove()

Placeholder for future logic.

beforeBurn()

Placeholder for future logic.

beforeIncreaseAllowance()

Placeholder for future logic.

beforeDecreaseAllowance()

Placeholder for future logic.

afterMint()

Placeholder to avoid breaking legacy interaction.

afterApprove()

Placeholder to avoid breaking legacy interaction.

afterBurn()

Placeholder to avoid breaking legacy interaction.

afterIncreaseAllowance()

Placeholder to avoid breaking legacy interaction.

afterDecreaseAllowance()

Placeholder to avoid breaking legacy interaction.

afterTransfer()

Placeholder to avoid breaking legacy interaction.

afterTransferFrom()

Placeholder to avoid breaking legacy interaction.

isAddressProtected

function isAddressProtected(address token, address protectedAddress) external view returns (bool)

Returns either true or false depending if the address has any protections set up on it.

Parameters:

getProtectedAddressStrategy

function getProtectedAddressStrategy(address token, address protectedAddress) external view returns (address)

Returns address of the strategy that the protected address is using. If address is not protected returns zero address.

Parameters:

Name
Type
Description

token

address

Token for which the protection is set.

protectedAddress

address

Address to check the protection strategy for.

setGuardian

function setGuardian(address newGuardian) external onlyLosslessAdmin whenNotPaused

Sets guardian contract's address. Can be called only by admin when contract is not paused.

Parameters:

Name
Type
Description

newGuardian

address

New guardian contract's address.

setProtectedAddress

function setProtectedAddress(address token, address protectedAddresss, ProtectionStrategy strategy) external onlyGuardian whenNotPaused

Sets token scoped protection on an address. Can be called only by the guardian when contract is not paused.

Parameters:

Name
Type
Description

token

address

Token for which the protection rules should be applied.

protectedAddress

address

Address to protect.

strategy

ProtectionStrategy

Strategy address that should be used when protecting the address.

setProtectedAddress()

removeProtectedAddress

function removeProtectedAddress(address token, address protectedAddresss) external onlyGuardian whenNotPaused

Removes token scoped protection. Can be called only by guardian contract when contract is not paused.

Parameters:

Name
Type
Description

token

address

Token for which the protection rules should be removed.

protectedAddress

address

Address to remove the protection from.

Last updated