mirror of
https://github.com/luxfi/erc-3643.git
synced 2026-10-30 16:58:28 +00:00
461 lines
22 KiB
Solidity
461 lines
22 KiB
Solidity
// SPDX-License-Identifier: GPL-3.0
|
|
//
|
|
// :+#####%%%%%%%%%%%%%%+
|
|
// .-*@@@%+.:+%@@@@@%%#***%@@%=
|
|
// :=*%@@@#=. :#@@% *@@@%=
|
|
// .-+*%@%*-.:+%@@@@@@+. -*+: .=#. :%@@@%-
|
|
// :=*@@@@%%@@@@@@@@@%@@@- .=#@@@%@%= =@@@@#.
|
|
// -=+#%@@%#*=:. :%@@@@%. -*@@#*@@@@@@@#=:- *@@@@+
|
|
// =@@%=:. :=: *@@@@@%#- =%*%@@@@#+-. =+ :%@@@%-
|
|
// -@@%. .+@@@ =+=-. @@#- +@@@%- =@@@@%:
|
|
// :@@@. .+@@#%: : .=*=-::.-%@@@+*@@= +@@@@#.
|
|
// %@@: +@%%* =%@@@@@@@@@@@#. .*@%- +@@@@*.
|
|
// #@@= .+@@@@%:=*@@@@@- :%@%: .*@@@@+
|
|
// *@@* +@@@#-@@%-:%@@* +@@#. :%@@@@-
|
|
// -@@% .:-=++*##%%%@@@@@@@@@@@@*. :@+.@@@%: .#@@+ =@@@@#:
|
|
// .@@@*-+*#%%%@@@@@@@@@@@@@@@@%%#**@@%@@@. *@=*@@# :#@%= .#@@@@#-
|
|
// -%@@@@@@@@@@@@@@@*+==-:-@@@= *@# .#@*-=*@@@@%= -%@@@* =@@@@@%-
|
|
// -+%@@@#. %@%%= -@@:+@: -@@* *@@*-:: -%@@%=. .*@@@@@#
|
|
// *@@@* +@* *@@##@@- #@*@@+ -@@= . :+@@@#: .-+@@@%+-
|
|
// +@@@%*@@:..=@@@@* .@@@* .#@#. .=+- .=%@@@*. :+#@@@@*=:
|
|
// =@@@@%@@@@@@@@@@@@@@@@@@@@@@%- :+#*. :*@@@%=. .=#@@@@%+:
|
|
// .%@@= ..... .=#@@+. .#@@@*: -*%@@@@%+.
|
|
// +@@#+===---:::... .=%@@*- +@@@+. -*@@@@@%+.
|
|
// -@@@@@@@@@@@@@@@@@@@@@@%@@@@= -@@@+ -#@@@@@#=.
|
|
// ..:::---===+++***###%%%@@@#- .#@@+ -*@@@@@#=.
|
|
// @@@@@@+. +@@*. .+@@@@@%=.
|
|
// -@@@@@= =@@%: -#@@@@%+.
|
|
// +@@@@@. =@@@= .+@@@@@*:
|
|
// #@@@@#:%@@#. :*@@@@#-
|
|
// @@@@@%@@@= :#@@@@+.
|
|
// :@@@@@@@#.:#@@@%-
|
|
// +@@@@@@-.*@@@*:
|
|
// #@@@@#.=@@@+.
|
|
// @@@@+-%@%=
|
|
// :@@@#%@%=
|
|
// +@@@@%-
|
|
// :#%%=
|
|
//
|
|
|
|
/**
|
|
* NOTICE
|
|
*
|
|
* The T-REX software is licensed under a proprietary license or the GPL v.3.
|
|
* If you choose to receive it under the GPL v.3 license, the following applies:
|
|
* T-REX is a suite of smart contracts implementing the ERC-3643 standard and
|
|
* developed by Tokeny to manage and transfer financial assets on EVM blockchains
|
|
*
|
|
* Copyright (C) 2023, Tokeny sàrl.
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
pragma solidity ^0.8.17;
|
|
|
|
import "../registry/interface/IIdentityRegistry.sol";
|
|
import "../compliance/modular/IModularCompliance.sol";
|
|
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
|
|
|
/// @dev interface
|
|
interface IToken is IERC20 {
|
|
|
|
/// events
|
|
|
|
/**
|
|
* this event is emitted when the token information is updated.
|
|
* the event is emitted by the token init function and by the setTokenInformation function
|
|
* `_newName` is the name of the token
|
|
* `_newSymbol` is the symbol of the token
|
|
* `_newDecimals` is the decimals of the token
|
|
* `_newVersion` is the version of the token, current version is 3.0
|
|
* `_newOnchainID` is the address of the onchainID of the token
|
|
*/
|
|
event UpdatedTokenInformation(string indexed _newName, string indexed _newSymbol, uint8 _newDecimals, string
|
|
_newVersion, address indexed _newOnchainID);
|
|
|
|
/**
|
|
* this event is emitted when the IdentityRegistry has been set for the token
|
|
* the event is emitted by the token constructor and by the setIdentityRegistry function
|
|
* `_identityRegistry` is the address of the Identity Registry of the token
|
|
*/
|
|
event IdentityRegistryAdded(address indexed _identityRegistry);
|
|
|
|
/**
|
|
* this event is emitted when the Compliance has been set for the token
|
|
* the event is emitted by the token constructor and by the setCompliance function
|
|
* `_compliance` is the address of the Compliance contract of the token
|
|
*/
|
|
event ComplianceAdded(address indexed _compliance);
|
|
|
|
/**
|
|
* this event is emitted when an investor successfully recovers his tokens
|
|
* the event is emitted by the recoveryAddress function
|
|
* `_lostWallet` is the address of the wallet that the investor lost access to
|
|
* `_newWallet` is the address of the wallet that the investor provided for the recovery
|
|
* `_investorOnchainID` is the address of the onchainID of the investor who asked for a recovery
|
|
*/
|
|
event RecoverySuccess(address indexed _lostWallet, address indexed _newWallet, address indexed _investorOnchainID);
|
|
|
|
/**
|
|
* this event is emitted when the wallet of an investor is frozen or unfrozen
|
|
* the event is emitted by setAddressFrozen and batchSetAddressFrozen functions
|
|
* `_userAddress` is the wallet of the investor that is concerned by the freezing status
|
|
* `_isFrozen` is the freezing status of the wallet
|
|
* if `_isFrozen` equals `true` the wallet is frozen after emission of the event
|
|
* if `_isFrozen` equals `false` the wallet is unfrozen after emission of the event
|
|
* `_owner` is the address of the agent who called the function to freeze the wallet
|
|
*/
|
|
event AddressFrozen(address indexed _userAddress, bool indexed _isFrozen, address indexed _owner);
|
|
|
|
/**
|
|
* this event is emitted when a certain amount of tokens is frozen on a wallet
|
|
* the event is emitted by freezePartialTokens and batchFreezePartialTokens functions
|
|
* `_userAddress` is the wallet of the investor that is concerned by the freezing status
|
|
* `_amount` is the amount of tokens that are frozen
|
|
*/
|
|
event TokensFrozen(address indexed _userAddress, uint256 _amount);
|
|
|
|
/**
|
|
* this event is emitted when a certain amount of tokens is unfrozen on a wallet
|
|
* the event is emitted by unfreezePartialTokens and batchUnfreezePartialTokens functions
|
|
* `_userAddress` is the wallet of the investor that is concerned by the freezing status
|
|
* `_amount` is the amount of tokens that are unfrozen
|
|
*/
|
|
event TokensUnfrozen(address indexed _userAddress, uint256 _amount);
|
|
|
|
/**
|
|
* this event is emitted when the token is paused
|
|
* the event is emitted by the pause function
|
|
* `_userAddress` is the address of the wallet that called the pause function
|
|
*/
|
|
event Paused(address _userAddress);
|
|
|
|
/**
|
|
* this event is emitted when the token is unpaused
|
|
* the event is emitted by the unpause function
|
|
* `_userAddress` is the address of the wallet that called the unpause function
|
|
*/
|
|
event Unpaused(address _userAddress);
|
|
|
|
/// functions
|
|
|
|
/**
|
|
* @dev sets the token name
|
|
* @param _name the name of token to set
|
|
* Only the owner of the token smart contract can call this function
|
|
* emits a `UpdatedTokenInformation` event
|
|
*/
|
|
function setName(string calldata _name) external;
|
|
|
|
/**
|
|
* @dev sets the token symbol
|
|
* @param _symbol the token symbol to set
|
|
* Only the owner of the token smart contract can call this function
|
|
* emits a `UpdatedTokenInformation` event
|
|
*/
|
|
function setSymbol(string calldata _symbol) external;
|
|
|
|
/**
|
|
* @dev sets the onchain ID of the token
|
|
* @param _onchainID the address of the onchain ID to set
|
|
* Only the owner of the token smart contract can call this function
|
|
* emits a `UpdatedTokenInformation` event
|
|
*/
|
|
function setOnchainID(address _onchainID) external;
|
|
|
|
/**
|
|
* @dev pauses the token contract, when contract is paused investors cannot transfer tokens anymore
|
|
* This function can only be called by a wallet set as agent of the token
|
|
* emits a `Paused` event
|
|
*/
|
|
function pause() external;
|
|
|
|
/**
|
|
* @dev unpauses the token contract, when contract is unpaused investors can transfer tokens
|
|
* if their wallet is not blocked & if the amount to transfer is <= to the amount of free tokens
|
|
* This function can only be called by a wallet set as agent of the token
|
|
* emits an `Unpaused` event
|
|
*/
|
|
function unpause() external;
|
|
|
|
/**
|
|
* @dev sets an address frozen status for this token.
|
|
* @param _userAddress The address for which to update frozen status
|
|
* @param _freeze Frozen status of the address
|
|
* This function can only be called by a wallet set as agent of the token
|
|
* emits an `AddressFrozen` event
|
|
*/
|
|
function setAddressFrozen(address _userAddress, bool _freeze) external;
|
|
|
|
/**
|
|
* @dev freezes token amount specified for given address.
|
|
* @param _userAddress The address for which to update frozen tokens
|
|
* @param _amount Amount of Tokens to be frozen
|
|
* This function can only be called by a wallet set as agent of the token
|
|
* emits a `TokensFrozen` event
|
|
*/
|
|
function freezePartialTokens(address _userAddress, uint256 _amount) external;
|
|
|
|
/**
|
|
* @dev unfreezes token amount specified for given address
|
|
* @param _userAddress The address for which to update frozen tokens
|
|
* @param _amount Amount of Tokens to be unfrozen
|
|
* This function can only be called by a wallet set as agent of the token
|
|
* emits a `TokensUnfrozen` event
|
|
*/
|
|
function unfreezePartialTokens(address _userAddress, uint256 _amount) external;
|
|
|
|
/**
|
|
* @dev sets the Identity Registry for the token
|
|
* @param _identityRegistry the address of the Identity Registry to set
|
|
* Only the owner of the token smart contract can call this function
|
|
* emits an `IdentityRegistryAdded` event
|
|
*/
|
|
function setIdentityRegistry(address _identityRegistry) external;
|
|
|
|
/**
|
|
* @dev sets the compliance contract of the token
|
|
* @param _compliance the address of the compliance contract to set
|
|
* Only the owner of the token smart contract can call this function
|
|
* calls bindToken on the compliance contract
|
|
* emits a `ComplianceAdded` event
|
|
*/
|
|
function setCompliance(address _compliance) external;
|
|
|
|
/**
|
|
* @dev force a transfer of tokens between 2 whitelisted wallets
|
|
* In case the `from` address has not enough free tokens (unfrozen tokens)
|
|
* but has a total balance higher or equal to the `amount`
|
|
* the amount of frozen tokens is reduced in order to have enough free tokens
|
|
* to proceed the transfer, in such a case, the remaining balance on the `from`
|
|
* account is 100% composed of frozen tokens post-transfer.
|
|
* Require that the `to` address is a verified address,
|
|
* @param _from The address of the sender
|
|
* @param _to The address of the receiver
|
|
* @param _amount The number of tokens to transfer
|
|
* @return `true` if successful and revert if unsuccessful
|
|
* This function can only be called by a wallet set as agent of the token
|
|
* emits a `TokensUnfrozen` event if `_amount` is higher than the free balance of `_from`
|
|
* emits a `Transfer` event
|
|
*/
|
|
function forcedTransfer(
|
|
address _from,
|
|
address _to,
|
|
uint256 _amount
|
|
) external returns (bool);
|
|
|
|
/**
|
|
* @dev mint tokens on a wallet
|
|
* Improved version of default mint method. Tokens can be minted
|
|
* to an address if only it is a verified address as per the security token.
|
|
* @param _to Address to mint the tokens to.
|
|
* @param _amount Amount of tokens to mint.
|
|
* This function can only be called by a wallet set as agent of the token
|
|
* emits a `Transfer` event
|
|
*/
|
|
function mint(address _to, uint256 _amount) external;
|
|
|
|
/**
|
|
* @dev burn tokens on a wallet
|
|
* In case the `account` address has not enough free tokens (unfrozen tokens)
|
|
* but has a total balance higher or equal to the `value` amount
|
|
* the amount of frozen tokens is reduced in order to have enough free tokens
|
|
* to proceed the burn, in such a case, the remaining balance on the `account`
|
|
* is 100% composed of frozen tokens post-transaction.
|
|
* @param _userAddress Address to burn the tokens from.
|
|
* @param _amount Amount of tokens to burn.
|
|
* This function can only be called by a wallet set as agent of the token
|
|
* emits a `TokensUnfrozen` event if `_amount` is higher than the free balance of `_userAddress`
|
|
* emits a `Transfer` event
|
|
*/
|
|
function burn(address _userAddress, uint256 _amount) external;
|
|
|
|
/**
|
|
* @dev recovery function used to force transfer tokens from a
|
|
* lost wallet to a new wallet for an investor.
|
|
* @param _lostWallet the wallet that the investor lost
|
|
* @param _newWallet the newly provided wallet on which tokens have to be transferred
|
|
* @param _investorOnchainID the onchainID of the investor asking for a recovery
|
|
* This function can only be called by a wallet set as agent of the token
|
|
* emits a `TokensUnfrozen` event if there is some frozen tokens on the lost wallet if the recovery process is successful
|
|
* emits a `Transfer` event if the recovery process is successful
|
|
* emits a `RecoverySuccess` event if the recovery process is successful
|
|
* emits a `RecoveryFails` event if the recovery process fails
|
|
*/
|
|
function recoveryAddress(
|
|
address _lostWallet,
|
|
address _newWallet,
|
|
address _investorOnchainID
|
|
) external returns (bool);
|
|
|
|
/**
|
|
* @dev function allowing to issue transfers in batch
|
|
* Require that the msg.sender and `to` addresses are not frozen.
|
|
* Require that the total value should not exceed available balance.
|
|
* Require that the `to` addresses are all verified addresses,
|
|
* IMPORTANT : THIS TRANSACTION COULD EXCEED GAS LIMIT IF `_toList.length` IS TOO HIGH,
|
|
* USE WITH CARE OR YOU COULD LOSE TX FEES WITH AN "OUT OF GAS" TRANSACTION
|
|
* @param _toList The addresses of the receivers
|
|
* @param _amounts The number of tokens to transfer to the corresponding receiver
|
|
* emits _toList.length `Transfer` events
|
|
*/
|
|
function batchTransfer(address[] calldata _toList, uint256[] calldata _amounts) external;
|
|
|
|
/**
|
|
* @dev function allowing to issue forced transfers in batch
|
|
* Require that `_amounts[i]` should not exceed available balance of `_fromList[i]`.
|
|
* Require that the `_toList` addresses are all verified addresses
|
|
* IMPORTANT : THIS TRANSACTION COULD EXCEED GAS LIMIT IF `_fromList.length` IS TOO HIGH,
|
|
* USE WITH CARE OR YOU COULD LOSE TX FEES WITH AN "OUT OF GAS" TRANSACTION
|
|
* @param _fromList The addresses of the senders
|
|
* @param _toList The addresses of the receivers
|
|
* @param _amounts The number of tokens to transfer to the corresponding receiver
|
|
* This function can only be called by a wallet set as agent of the token
|
|
* emits `TokensUnfrozen` events if `_amounts[i]` is higher than the free balance of `_fromList[i]`
|
|
* emits _fromList.length `Transfer` events
|
|
*/
|
|
function batchForcedTransfer(
|
|
address[] calldata _fromList,
|
|
address[] calldata _toList,
|
|
uint256[] calldata _amounts
|
|
) external;
|
|
|
|
/**
|
|
* @dev function allowing to mint tokens in batch
|
|
* Require that the `_toList` addresses are all verified addresses
|
|
* IMPORTANT : THIS TRANSACTION COULD EXCEED GAS LIMIT IF `_toList.length` IS TOO HIGH,
|
|
* USE WITH CARE OR YOU COULD LOSE TX FEES WITH AN "OUT OF GAS" TRANSACTION
|
|
* @param _toList The addresses of the receivers
|
|
* @param _amounts The number of tokens to mint to the corresponding receiver
|
|
* This function can only be called by a wallet set as agent of the token
|
|
* emits _toList.length `Transfer` events
|
|
*/
|
|
function batchMint(address[] calldata _toList, uint256[] calldata _amounts) external;
|
|
|
|
/**
|
|
* @dev function allowing to burn tokens in batch
|
|
* Require that the `_userAddresses` addresses are all verified addresses
|
|
* IMPORTANT : THIS TRANSACTION COULD EXCEED GAS LIMIT IF `_userAddresses.length` IS TOO HIGH,
|
|
* USE WITH CARE OR YOU COULD LOSE TX FEES WITH AN "OUT OF GAS" TRANSACTION
|
|
* @param _userAddresses The addresses of the wallets concerned by the burn
|
|
* @param _amounts The number of tokens to burn from the corresponding wallets
|
|
* This function can only be called by a wallet set as agent of the token
|
|
* emits _userAddresses.length `Transfer` events
|
|
*/
|
|
function batchBurn(address[] calldata _userAddresses, uint256[] calldata _amounts) external;
|
|
|
|
/**
|
|
* @dev function allowing to set frozen addresses in batch
|
|
* IMPORTANT : THIS TRANSACTION COULD EXCEED GAS LIMIT IF `_userAddresses.length` IS TOO HIGH,
|
|
* USE WITH CARE OR YOU COULD LOSE TX FEES WITH AN "OUT OF GAS" TRANSACTION
|
|
* @param _userAddresses The addresses for which to update frozen status
|
|
* @param _freeze Frozen status of the corresponding address
|
|
* This function can only be called by a wallet set as agent of the token
|
|
* emits _userAddresses.length `AddressFrozen` events
|
|
*/
|
|
function batchSetAddressFrozen(address[] calldata _userAddresses, bool[] calldata _freeze) external;
|
|
|
|
/**
|
|
* @dev function allowing to freeze tokens partially in batch
|
|
* IMPORTANT : THIS TRANSACTION COULD EXCEED GAS LIMIT IF `_userAddresses.length` IS TOO HIGH,
|
|
* USE WITH CARE OR YOU COULD LOSE TX FEES WITH AN "OUT OF GAS" TRANSACTION
|
|
* @param _userAddresses The addresses on which tokens need to be frozen
|
|
* @param _amounts the amount of tokens to freeze on the corresponding address
|
|
* This function can only be called by a wallet set as agent of the token
|
|
* emits _userAddresses.length `TokensFrozen` events
|
|
*/
|
|
function batchFreezePartialTokens(address[] calldata _userAddresses, uint256[] calldata _amounts) external;
|
|
|
|
/**
|
|
* @dev function allowing to unfreeze tokens partially in batch
|
|
* IMPORTANT : THIS TRANSACTION COULD EXCEED GAS LIMIT IF `_userAddresses.length` IS TOO HIGH,
|
|
* USE WITH CARE OR YOU COULD LOSE TX FEES WITH AN "OUT OF GAS" TRANSACTION
|
|
* @param _userAddresses The addresses on which tokens need to be unfrozen
|
|
* @param _amounts the amount of tokens to unfreeze on the corresponding address
|
|
* This function can only be called by a wallet set as agent of the token
|
|
* emits _userAddresses.length `TokensUnfrozen` events
|
|
*/
|
|
function batchUnfreezePartialTokens(address[] calldata _userAddresses, uint256[] calldata _amounts) external;
|
|
|
|
/**
|
|
* @dev Returns the number of decimals used to get its user representation.
|
|
* For example, if `decimals` equals `2`, a balance of `505` tokens should
|
|
* be displayed to a user as `5,05` (`505 / 1 ** 2`).
|
|
*
|
|
* Tokens usually opt for a value of 18, imitating the relationship between
|
|
* Ether and Wei.
|
|
*
|
|
* NOTE: This information is only used for _display_ purposes: it in
|
|
* no way affects any of the arithmetic of the contract, including
|
|
* balanceOf() and transfer().
|
|
*/
|
|
function decimals() external view returns (uint8);
|
|
|
|
/**
|
|
* @dev Returns the name of the token.
|
|
*/
|
|
function name() external view returns (string memory);
|
|
|
|
/**
|
|
* @dev Returns the address of the onchainID of the token.
|
|
* the onchainID of the token gives all the information available
|
|
* about the token and is managed by the token issuer or his agent.
|
|
*/
|
|
function onchainID() external view returns (address);
|
|
|
|
/**
|
|
* @dev Returns the symbol of the token, usually a shorter version of the
|
|
* name.
|
|
*/
|
|
function symbol() external view returns (string memory);
|
|
|
|
/**
|
|
* @dev Returns the TREX version of the token.
|
|
* current version is 3.0.0
|
|
*/
|
|
function version() external view returns (string memory);
|
|
|
|
/**
|
|
* @dev Returns the Identity Registry linked to the token
|
|
*/
|
|
function identityRegistry() external view returns (IIdentityRegistry);
|
|
|
|
/**
|
|
* @dev Returns the Compliance contract linked to the token
|
|
*/
|
|
function compliance() external view returns (IModularCompliance);
|
|
|
|
/**
|
|
* @dev Returns true if the contract is paused, and false otherwise.
|
|
*/
|
|
function paused() external view returns (bool);
|
|
|
|
/**
|
|
* @dev Returns the freezing status of a wallet
|
|
* if isFrozen returns `true` the wallet is frozen
|
|
* if isFrozen returns `false` the wallet is not frozen
|
|
* isFrozen returning `true` doesn't mean that the balance is free, tokens could be blocked by
|
|
* a partial freeze or the whole token could be blocked by pause
|
|
* @param _userAddress the address of the wallet on which isFrozen is called
|
|
*/
|
|
function isFrozen(address _userAddress) external view returns (bool);
|
|
|
|
/**
|
|
* @dev Returns the amount of tokens that are partially frozen on a wallet
|
|
* the amount of frozen tokens is always <= to the total balance of the wallet
|
|
* @param _userAddress the address of the wallet on which getFrozenTokens is called
|
|
*/
|
|
function getFrozenTokens(address _userAddress) external view returns (uint256);
|
|
}
|