Transfer Fees Module

This module introduces the ability to levy fees on token transfers, offering token issuers the flexibility to set the fee percentage and designate a specific wallet to collect these fees. It also allows for the exclusion of certain addresses from the fee mechanism, providing a way to tailor the fee structure to accommodate operational needs or incentivize particular transaction patterns within the ecosystem.

How Does It Work?

  • Token owners set the fee rates and collector wallets.
    • The collector wallet must be verified for the token.
  • The minimum fee rate is 0.01% but must be given in uint format. So, when defining fee rates:
    • 1 = 0.01%
    • 10 = 0.1%
    • 100 = 1%
    • 1000 = 10%
    • 10000 = 100%
    • It can also be 0, which means no fee will be charged.
  • The transfer fee is transferred from the receiver to the collector's wallet after the transfer process (with the forcedTransfer function of the token). Therefore, the transfer fees module must be added to the token as an agent, otherwise, the transfer cannot be made.

Events

ComplianceBound

This event is emitted when the compliance contract is bound to the module
the event is emitted by 'bindCompliance'
_compliance is the address of the compliance contract being bound

event ComplianceBound(
  address indexed _compliance
);

ComplianceUnbound

This event is emitted when the compliance contract is unbound from the module
the event is emitted by 'unbindCompliance'
_compliance is the address of the compliance contract being unbound

event ComplianceUnbound(
  address indexed _compliance
);

FeeUpdated

This event is emitted whenever a fee definition is updated for the given compliance address
the event is emitted by 'setFee'
compliance is the compliance contract address
_rate is the rate of the fee (0.01% = 1, 1% = 100, 100% = 10000)
_collector is the collector wallet address

event FeeUpdated(
	address indexed compliance, 
  uint256 _rate, 
  address _collector
);

Functions

bindCompliance

Binds the module to a compliance contract. Once the module is bound, the compliance contract can interact with the module.
parameter 1: _compliance the address of the compliance contract
emits a ComplianceBound event
This function can be called ONLY by the compliance contract itself (_compliance), through the addModule function, which calls bindCompliance the module cannot be already bound to the compliance.

function bindCompliance(
	address _compliance
) external;

unbindCompliance

Unbinds the module from a compliance contract. Once the module is unbound, the compliance contract cannot interact with the module anymore.
parameter 1: _compliance the address of the compliance contract.
emits a ComplianceUnbound event
This function can be called ONLY by the compliance contract itself (_compliance), removeModule function, which calls unbindCompliance.

function unbindCompliance(
	address _compliance
) external;

isComplianceBound

Getter for compliance binding status on module
parameter 1: _compliance the address of the compliance contract
returns TRUE if the compliance is bound to the module, FALSE otherwise

function isComplianceBound(
	address _compliance
) external view returns (bool);

setFee

Sets the fee rate and collector of the given compliance
This function can only be called by the owner of the token
parameter 1: _compliance the address of the compliance contract
parameter 2: _rate the rate of the fee (0.01% = 1, 1% = 100, 100% = 10000)
parameter 3: _collector the collector wallet address
emits a FeeUpdated event

function setFee(
	address _compliance, 
   uint256 _rate, 
   address _collector
) external;

getFee

Function for getting compliance fee info
parameter 1: compliance the compliance smart contract address

Returns the fee info of the compliance

function getFee(
	address compliance
 ) external view returns (Fee memory);

moduleCheck

The compliance check on the module for a specific transaction on a specific compliance contract. This function is used to check if the transfer is allowed by the module.
parameter 1: _from the address of the transfer sender
parameter 2: _to the address of the transfer receiver
parameter 3: _value the amount of tokens sent
parameter 4: _compliance the address of the compliance contract concerned by the transfer action
Returns TRUE if the module allows the transfer, FALSE otherwise

function moduleCheck(
	address _from, 
	address _to, 
	uint256 _value, 
	address _compliance
) external view;

moduleTransferAction

The action performed on the module during a transfer action. It increases the transfer counters.
parameter 1: _from the address of the transfer sender
parameter 2: _to the address of the transfer receiver
parameter 3: _value the amount of tokens sent
This function can be called only on a compliance contract that is bound to the module

function moduleTransferAction(
	address _from, 
	address _to, 
	uint256 _value
) external;

moduleMintAction

The action performed on the module during a mint action. This function is used to update variables of the module upon minting if it is required. This function is not implemented in this contract.
parameter 1: _to the address used for minting
parameter 2: _value the amount of tokens minted
This function can be called only on a compliance contract that is bound to the module

function moduleMintAction(
	address _to, 
	uint256 _value
) external;

moduleBurnAction

The action performed on the module during a burn action. This function is used to update variables of the module upon burning if it is required. This function is not implemented in this contract.
parameter 1: _from the address on which tokens are burnt
parameter 2: _value the amount of tokens burnt
This function can be called only on a compliance contract that is bound to the module

function moduleBurnAction(
	address _from, 
	uint256 _value
) external;

upgradeTo (UUPS)

Upgrade the implementation of the proxy to newImplementation

parameter 1: newImplementation the address of the new implementation contract.

This function can only be called by the proxy contract.

function upgradeTo(address newImplementation) public;