arrow-left

Only this pageAll pages
gitbookPowered by GitBook
1 of 39

Frictionless Protocol

Loading...

Protocol Overview

Loading...

Loading...

Loading...

SMART CONTRACTS

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

API

Loading...

Loading...

Loading...

Loading...

Welcome to Frictionless Protocol

The Frictionless protocol is an institutional-grade venue built on EVM-compatible smart contracts for the issuance, distribution and settlement of digital securities in the private markets. The process involves dematerializing credit & infrastructure funds, ETFs or AMCs into risk-profiled future cash flow tokens, in the form of ERC-3643 digital securities which are aligned with the distribution schedule of the Manager.

Via strategies, Investors can invest in a diversified cross-section of funds using instant atomic settlement in attested 1:1 backed FIAT deposit tokens, which are banked with a G-SIBarrow-up-right in Luxembourg.

This tokenization lego-brick approach ensures digital securities can be instantly composed into secondary trades, semi-liquid & automatic structured products and distributed between Investors in a privacy-protected mode for a few cents. All tokens within the protocol are permissioned tokens built under ERC-3643 specification for permissioned tokensarrow-up-right to ensure that there is instant delivery versus payment, whilst ensuring the privacy of the Investor is protected. The Frictionless Markets APIs interact with these smart contracts to orchestrate the mint, transfer and burn of the various tokens in the protocol.

circle-info

Join the community on Discord !

herearrow-up-right

Compliance

These contracts define the compliance layer for permissioned network participants (KYC/AML, Sanctions, PEP screening), the offering rules and the transfer rules for tokens, which ensures transfers are conducted in line with the legal and regulatory guardrails of MiFID II.

The compliance modules are upgradeable and are tied to specific tokens.

Participants

The Frictionless protocol is a market infrastructure for the issuance, trade, and settlement of digital securities in the private markets. The protocol caters for various roles and responsibilities both within the smart contracts and the API systems, enabling the various market functions to be performed according to the regulatory posture of Frictionless Markets S.à r.l, the legal issuer of digital securities in Luxembourg under MiFID II and the broader E.U.

circle-check

Frictionless Markets S.à r.l and its securitization fund (FRICTIONLESS MARKETS SECURITIES FT) is the legal issuer of digital securities in compliance with MiFID II (2014/65/EU) regulation. Frictionless Markets S.à r.l operates the PROTOCOL_ADMIN and PROTOCOL_TREASURY.

Where required and directed by a PERMISSIONED_MANAGER, Frictionless Markets S.à r.l provisions and/or operates a PERMISSIONED_CUSTODIAN on the protocol for the custody of securities or cash in accordance with the securitization laws of Luxembourg.

circle-info

For more information on the legal structure of the FRICTIONLESS MARKETS SECURITIES FT, consult our

chevron-rightPROTOCOL_ADMINhashtag

The protocol admin is the owner and deployer of the smart contracts. The Owner role is defined within the OpenZepplin context. The PROTOCOL_ADMIN is not permitted to custody any of the tokens within the protocol.

The ERC-3643 definition of the role is isOwner

chevron-rightPROTOCOL_TREASURYhashtag

Represents the treasury in the protocol. The PROTOCOL_TREASURY is an Agent under the definition of the ERC-3643 specification and is responsible for the lifecycle management of all tokens in the protocol. Frictionless Markets is the legal entity which is responsible for the treasury management of the non-co-mingled FIAT deposit & redemptions in multi-currency ledgers at G-SIB providers in Luxembourg under the role PROTOCOL_TREASURY.

The ERC-3643 definition of the role is isAgent

chevron-rightPERMISSIONED_CUSTODIANhashtag

The Permissioned Custodian is the custodian address and OnChain Identity which can custody any of the Frictionless protocol tokens.

The ERC-3643 role is a Custom Compliance role.

chevron-rightPERMISSIONED_INVESTORhashtag

A permissioned Investor in the protocol, is an investor who is compliant with the specification of the FrictionlessOnChainAssetToken and the private placement memorandum of the securitization structure and fund. The Frictionless protocol is open to accredited (professional client) investors only in compliance with (2014/65/EU) regulation, MiFID II. The onboarding of Investors is conducted off-chain, including KYC/AML, Subscription Agreement, etc, which are then added to the claim of the Investors' OnChainId.

The ERC-3643 role is a Custom Compliance role.

chevron-rightPERMISSIONED_MANAGERhashtag

A permissioned Manager in the protocol is a Manager or GP utilising both the technology protocol and the fund services of Frictionless Markets to issue their FrictionlessOnChainAssetToken. A PERMISSIONED_MANAGER may also interact with the FundDepositToken to accept & settle payments for Digital Securities.

The ERC-3643 role is a Custom Compliance role.

chevron-rightPERMISSIONED_FUND_ACCOUNTANThashtag

A permissioned Fund Accountant in the protocol is an independent Fund Accountant with access to the underlying IBAN accounts for a FrictionlessFundDepositToken, so they can provide certified attestations for the balance of the accounts at regular intervals. A PERMISSIONED_FUND_ACCOUNTANT interacts with the IFrictionlessAttestationManager to provide this market feature.

The ERC-3643 role is a Custom Compliance role.

chevron-rightPERMISSIONED_CALCULATING_AGENThashtag

A permissioned Calculating Agent in the protocol is an Agent who is permitted to calculate the market value of a FrictionlessOnChainAssetToken with the consent of the PERMISSIONED_MANAGER, so the cash waterfalls may be calculated for the Investors.

The role is not fully supported in the protocol yet.

The ERC-3643 role is a Custom Compliance role.

chevron-rightPERMISSIONED_TRANSFER_AGENThashtag

A permissioned Transfer Agent in the protocol is an Agent who has the provision to transfer securities independently of the PROTOCOL_TREASURY.

The role is not fully supported in the protocol yet.

The ERC-3643 role is a Custom Compliance role.

Audit & Security

The smart contracts powering the Frictionless protocol have undergone a meticulous audit by Hacken.ioarrow-up-right, a renowned name in blockchain audit and security.

circle-check

The Frictionless Protocol smart contracts have achieved a perfect 10/10 rating,arrow-up-right attesting to the robustness and security of our blockchain infrastructure. This accomplishment reflects our unwavering commitment to ensuring the safety and trustworthiness of our platform.

10/10 - Security Score

10/10 - Code Quality Score

100% - Security Score

10/10 - Documentation Quality Score

The comprehensive audit report conducted by Hacken.io is now available for review at We encourage anyone interacting with the Frictionless protocol to explore the detailed findings, recommendations, and security measures outlined in the report.

Throughout the auditing process, we maintained a transparent and collaborative tracking with the Hacken.io team. This approach allowed us to address potential vulnerabilities promptly and work together to enhance the overall security of our smart contracts.

We are proud to announce that the are released under the MIT license. This open-source licensing model reflects our dedication to transparency, collaboration, and community involvement. The MIT license allows developers and stakeholders to freely use, modify, and distribute our smart contracts while providing clear guidelines on attribution and liability.

Frictionless Tokens

The Frictionless Tokens describe the tokens which are emitted by the Frictionless protocol to represent Asset, Securities and Deposits. These tokens are based on the ERC-3643 arrow-up-rightspecification of IToken.

The following diagram describes the high-level interaction and composition of a Frictionless token.

Schematic relationship of Frictionless Tokens

Overview

The Frictionless smart contracts are an suite of available under the permissive which enable compliant digital securities transfer, payment and settlement on EVM-compatible blockchains, such as Avalance C-Chain, Ethereum or Polygon.

circle-info

The Frictionless smart contracts extend the T-REX specification with specific features to operate private placements under MiFID II regulation.

IBasicFrictionlessToken

Inherits: IToken

Author: DEFYCA Labs S.à.r.l

Copyright © 2023 DEFYCA Labs S.à.r.l Permission is hereby granted, free of charge, to any person obtaining a copy of the Frictionless protocol smart contracts (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL DEFYCA LABS S.à.r.l BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Smart Contract Docs

The Frictionless protocol smart contracts are documented using the standard.

chevron-righthashtag

The Frictionless Tokens describe the tokens which are emitted by the Frictionless protocol to represent Asset, Securities and Deposits. These tokens are based on thespecification of IToken.

chevron-right
legal & fund documentationarrow-up-right
hashtag

These contracts define the compliance layer for permissioned network participants (KYC/AML, Sanctions, PEP screening), the offering rules and the transfer rules for tokens, which ensures transfers are conducted in line with the legal and regulatory guardrails of MiFID II.

chevron-rightAutomated Fee Collectionhashtag

The Frictionless protocol is designed to automate cash operations across the lifecycle of a fund, part of this automation is the collection of contracted fee structures within a fund, such as management and/or performance fees. The smart contracts for transfer, ERC20 swap and FX swaps may be programmed to automatically collect fees for Managers, opening new revenue streams for Managers whilst ensuring the visibility of fees for Investors and Managers alike.

chevron-rightManager Contractshashtag

The Manager Contracts are the main entry points to the Frictionless protocol, they perform market functions such as permission management, treasury operations, issuance, transfer and settlement of securities, and attestations of deposits (proof-of-reserve) for the underlying of FrictionlessFundDepositTokens.

chevron-rightFrictionless FX Swapshashtag

Frictionless FX Swaps enable Investors to invest instantly, securely and risk-free at super low cost in multiple currencies.

The FX Swap contracts in the Frictionless protocol provide an instant/atomic swap of a currency pair at a quoted spot of forward rate.

chevron-rightERC20 Swapshashtag

ERC20 Swaps were designed by the developers in the Frictionless protocol to risk off permissionless stablecoins such as USDC or USDT.

Permissionless are a great innovation from the crypto markets which were designed for permissionless crypto referencing to US Dollars, however handling stablecoins for traditional institutional partners is still a risky proposition.

Using the ERC20 Converter contracts, FrictionlessFundDepositTokens can be converted to/from stablecoins using the Frictionless protocol to help Managers accept stablecoins whilst off-loading their associated risks, such as de-peg events, underlying community bank reliance and liquidity risks.

NATSPECarrow-up-right
Frictionless Tokens
ERC-3643 arrow-up-right
Compliance
Frictionless Protocol Audit Results.arrow-up-right
processarrow-up-right
Frictionless Protocol smart contractsarrow-up-right

License

The Frictionless Markets APIs are offered under commercial license terms if you wish to license the technology including the secure APIs, GraphQL data store, UI and automation services, please contact the team at https://www.frictionless.markets/arrow-up-right or via LinkedInarrow-up-right profile.

The IBasicFrictionlessToken Represents the base interface for Frictionless protocol tokens, this interface is used to determine a token type.

hashtag
Functions

hashtag
setFrictionlessTokenType

Sets the token type according to the specified enumeration

Parameters

Name
Type
Description

newTokenType_

FrictionlessTokenTypes

the token type to set

hashtag
getFrictionlessTokenType

Returns the token type according to the specified enumeration

Returns

Name
Type
Description

<none>

FrictionlessTokenTypes

FrictionlessTokenTypes the token type according to the specified enumeration

hashtag
Errors

hashtag
BasicFrictionlessTokenUnableToUpdateFrictionlessTokenType

error thrown if an attempt to set an invalid token type during function setFrictionlessTokenType

hashtag
Enums

hashtag
FrictionlessTokenTypes

Enumeration to represent each of the tokens in the Frictionless protocol.

Git Sourcearrow-up-right
function setFrictionlessTokenType(FrictionlessTokenTypes newTokenType_) external;
function getFrictionlessTokenType() external view returns (FrictionlessTokenTypes);
error BasicFrictionlessTokenUnableToUpdateFrictionlessTokenType();
enum FrictionlessTokenTypes {
    NONE,
    FUND_DEPOSIT_TOKEN,
    DIGITAL_SECURITY_TOKEN,
    ON_CHAIN_ASSET_TOKEN
}
hashtag
Features

hashtag
Smart Contract Architecture

The Frictionless protocol is essentially a decentralised system of privacy-protecting proofs and permissioned tokens that can only be transferred under tight controls in accordance with the regulatory rules of the underlying funds and securities which are tokenized.

The Frictionless protocol extends the ERC-3643arrow-up-right specification with specific features to operate private placements under MiFID II regulation. The are six main pillars of the Frictionless protocol as illustrated in the diagram below.

Frictionless protocol main smart contract pillars
  1. Identity Management - based on OnChainId all participants in the Frictionless protocol are permissioned with specific roles, defining the actions and token classes they can interact with.

  2. Compliance - based on the ERC-3643 specification, upgradable modules for compliance enable the compliant transfer of token classes in the protocol.

  3. Frictionless Tokens - based on the ERC-3643 specification, these are the tokens circulated in the protocol to represent securities, assets, cash contributions, cash distributions and settlements.

  4. Treasury Management - provides the smart contract functions to mint, transfer and burn token classes in the protocol.

  5. Proof-of-Reserve - provides independent attestations over the currencies underpinning FrictionlessFundDepositTokens.

  6. Transfer Agency - provides the controlled transfer of tokens between participants under strict compliance. This also includes the facility to swap tokens, such as stablecoins with FrictionlessFundDepositTokens or FX swaps of FrictionlessFundDepositTokens of various denominations.

The Smart Contract Docs cover these topics in depth with visual explanations of how each contract functions along with its NATSPEC documentation.

audited
smart contractsarrow-up-right
MIT licensearrow-up-right
ERC-3643arrow-up-right

IFrictionlessFundDepositToken

Git Sourcearrow-up-right

Inherits: IBasicFrictionlessToken

Author: DEFYCA Labs S.à.r.l

Copyright © 2023 DEFYCA Labs S.à.r.l Permission is hereby granted, free of charge, to any person obtaining a copy of the Frictionless protocol smart contracts (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL DEFYCA LABS S.à.r.l BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

A Fund Deposit Token represents a permissioned Investors FIAT contribution to a specific fund IBAN in a denominated FIAT currency. The Fund Deposit Token is used as a means of payment and settlement. The Fund Deposit Token can only be transferred between permissioned Investors in the fund. A daily attestation of the fund IBAN serves to prove the 1:1 backing with FIAT. Exclusively under Frictionless Markets S.à.r.l issuance terms Investors holding a FrictionlessFundDepositToken have the legal right to the FIAT value held in the fund IBAN account.

hashtag
Functions

hashtag
setInitData

Sets the immutable data for the FrictionlessFundDepositToken

Parameters

Name
Type
Description

hashtag
getCurrency

Get the currency the FIAT denomination of the deposit token.

Returns

Name
Type
Description

hashtag
getDescription

Get the description the description of the deposit token.

Returns

Name
Type
Description

hashtag
getFundIBAN

Get the IBAN which Frictionless Markets S.à.r.l holds a matching FIAT currency ledger with a G-SIB for this currency, attestations are provided on this IBAN. This is restricted to onlyAgent roles.

Returns

Name
Type
Description

hashtag
Errors

hashtag
FrictionlessFundDepositTokenUnableToUpdateInitData

error throw if there is an attempt to modify the immutable data.

hashtag
Structs

hashtag
FFDImmutableData

Struct which represents the immutable data in the Token. Once set it cannot be modified.

Overview

circle-exclamation

Release v2.0.0 of the Frictionless Markets APIs built on OpenAPI specification on confidential compute cluster to ISO-27001 and SOC-2 specifications are due for release on Jan 24th 2024 (24/1/24).

Please check back with us or watch for announcements on our socials and LinkedInarrow-up-right.

The Frictionless platform is built on a microservice pattern, deployed on Confidential Google clusters for dedicated ISO-27001 secured environments, the stack is built to standard and interacts with the Frictionless via our internal proprietary Frictionless Chain Service built over the massively scalable and .

How it works

The Frictionless protocol is the technology enabler which translates real-world investments into legal, compliant and transferrable tokenized securities through a Luxembourg structure, operated by Frictionless Markets S.à r.l and its securitization structures.

circle-check

Frictionless Markets S.à.r.l and its securitization fund (FRICTIONLESS MARKETS SECURITIES FT) is the legal issuer of digital securities in compliance with MiFID II (2014/65/EU) regulation.

circle-info

Kubernetesarrow-up-right
OpenAPIarrow-up-right
smart contracts
Neo4Jarrow-up-right
graphQLarrow-up-right
High Level Architecture of Frictionless Protocol & APIs

Frictionless Markets APIs

circle-exclamation

Release v2.0.0 of the Frictionless Markets APIs built on OpenAPI specification on confidential compute cluster to ISO-27001 and SOC-2 specifications are due for release on Jan 24th 2024 (24/1/24).

Please check back with us or watch for announcements on our socials and LinkedInarrow-up-right.

Security & Access

circle-exclamation

Release v2.0.0 of the Frictionless Markets APIs built on OpenAPI specification on confidential compute cluster to ISO-27001 and SOC-2 specifications are due for release on Jan 24th 2024 (24/1/24).

Please check back with us or watch for announcements on our socials and LinkedInarrow-up-right.

initData

FFDImmutableData

the immutable data for the FrictionlessFundDepositToken

<none>

string

the currency the FIAT denomination of the deposit token.

<none>

string

the description the description of the deposit token

<none>

string

the IBAN which Frictionless Markets S.à.r.l holds a matching FIAT currency ledger with a G-SIB for this currency, attestations are provided on this IBAN.

function setInitData(FFDImmutableData calldata initData) external;
function getCurrency() external view returns (string memory);
function getDescription() external view returns (string memory);
function getFundIBAN() external returns (string memory);
error FrictionlessFundDepositTokenUnableToUpdateInitData();
struct FFDImmutableData {
    string currency;
    string description;
    string fundIBAN;
}
For more information on the legal structure of the FRICTIONLESS MARKETS SECURITIES FT, consult our legal & fund documentationarrow-up-right

There are many tokenization offerings in the market place and the industry is witnessing new entrants each with its respective niche and focus. The Frictionless protocol focus is specifically on the private markets and specifically on providing the legally compliant market infrastructure to enable Managers and GPs to tokenize their funds and offerings, whilst offering Investors a frictionless, low minimum, and transparent access point to the private markets on a global basis.

hashtag
Core Layers

As a market infrastructure, the Frictionless protocol provides the three core layers to enable Investors to invest in the best private markets offerings on a global basis. These sections cover the basics of securitization, tokenization and distribution.

  1. Securitization

  2. Tokenization

  3. Distribution

Core Layers of Frictionless protocol, Securitization, Tokenization and Distribution.

hashtag
1. Securitization

The Frictionless Markets team supports a wide variety of securitizations in Luxembourg. The securitizations can be "true sale" or "synthetic" securitizations and are issued from bankruptcy remote and orphan entity-protected structures.

A securitization transaction involves establishing a securitization entity in Luxembourg to assume the risk associated with future cash flows tied to receivables, assets, or activities conducted by third parties known as the Underlying Assets. Simultaneously, the entity issues securities, typically in the form of notes, whose yield and value are connected to the performance of the Underlying Assets. These securities are then offered to professional investors on the financial markets in a tokenized format using the Frictionless protocol.

The Frictionless Markets team establishes and operates the securitization structures, providing the fund administration, fund structuring, cash operations and fund reporting services under Luxembourg securitization law.

hashtag
2. Tokenization

The Frictionless protocol includes:

  1. A suite of smart contracts to represent:

    1. Funds/Notes - Frictionless OnChain Assets: The FrictionlessOnChainAssetToken represents a listed fund with the informational and legal rights to the underlying. This includes all the informational rights on the underlying and its associated maturity. A FrictionlessOnChainAssetToken is issued as a digital twin for each specific note in a compartment within the Frictionless Markets fund structure.

    2. Cash - Frictionless Deposit Tokens: A FrictionlessFundDepositToken represents a permissioned Investors FIAT contribution to a specific fund IBAN in a denominated FIAT currency. The FrictionlessFundDepositToken is used as a means of payment and settlement record. The FrictionlessFundDepositToken can only be transferred between permissioned Investors and Managers in the fund as a record of FIAT transfers within the Fund. A daily attestation of the fund IBAN serves to prove the 1:1 backing with FIAT. Market participants holding a FrictionlessFundDepositToken have the legal claim to the FIAT value held in the fund IBAN account under the final terms of the financial instrument issued by the note tracking the FrictionlessFundDepositToken.

    3. Securities - Frictionless Digital Security Tokens: This is the which represents the future cash flow from the FrictionlessOnChainAssetToken and is purchased by the Investor using FrictionlessFundDepositToken's. These digital securities are permissioned and transferable between permissioned Investors in a permissioned market. This token is linked to the FrictionlessOnChainAssetToken and denominated in a FIAT currency at a future date for settlement.

  2. Smart contracts to execute the of Frictionless tokens in primary and secondary transactions

  3. Smart contracts to ERC20 tokens (stablecoins) to/from Frictionless Deposit Tokens, enabling Managers to risk off stablecoin contributions to their respective funds/

  4. Smart contracts to Frictionless Deposit Tokens of different FIAT denominations using spot and forward rates, enabling Investors to invest and settle in multiple currencies.

  5. Smart contracts to manage the of market participants in accordance with regulation.

  6. APIs and a Tokenization Engine to orchestrate and automate complex Manager workflows such as:

    1. Subscriptions

    2. Capital Calls

  7. Wallet Infrastructure enabling the custody of tokenized funds/notes, the collection of fees, custody of ERC20 stablecoins for the PROTOCOL_TREASURY and the wallet infrastructure required to sign and execute transactions on the blockchain.

The Frictionless Markets team operates the protocol, granting access to Managers to tokenize their funds and automate their fund administration services from the Frictionless Markets Manager Interface, API or smart contracts.

hashtag
3. Distribution

Managers can onboard Investors directly or link into permissioned distribution agents on the Frictionless protocol to distribute their tokenized securities on a global basis., these include:

  1. Private Placement Agents

  2. Global Wealth Advisors

  3. Private Banks

  4. Digital Security Exchanges

The distribution layer of the Frictionless protocol enables Investors to onboard into tokenized funds using their OnChainIdarrow-up-right, direct KYC/AML subscription or via reliance letter.

Investors invest via subscriptions or subscription contracts to the tokenized fund/note in accordance with MiFID II regulation.

The investment and settlement of tokenized securities are carried out using Frictionless Deposit Tokens, which is a non-invasive and seamless conversion between FIAT contributions or settlement and their tokenized representation.

The Frictionless Markets team operates the protocol, granting access to Distribution Agents and their Investor base to a wide variety of tokenized funds from the world's best GPs and Managers.

Distribution Agents can manage:

  • Subscriptions to Funds for their Investor base.

  • Capital Calls and reporting for their Investor base.

  • Cash Distributions and reporting for their Investor base.

  • Portfolio Compositions for their Investor base.

hashtag
Supported Securitizations

Securitization encompasses a wide range of asset types, including:

  1. Receivables such as loans

  2. Liquid assets like bonds or securities

  3. Illiquid assets including private equity and real estate

  4. Derivative instruments

  5. Intellectual property generating royalty streams

  6. Cash flow associated with risk or contractual agreements

  7. Shares in other entities, PE, Credit, Infrastructure funds, or deals

Frictionless Markets supports the issuance of Notes, Tracker Certificates, and Actively Managed Certificates in multiple currencies. In general, the Frictionless Markets team and the Frictionless protocol support the following securitization & tokenization use cases:

circle-info

For more information on the securitization benefits from Frictionless Markets and an in-depth understanding of our offerings, consult our legal & fund documentationarrow-up-right.

hashtag
Lifecycle of a Transaction

The act of correctly securitizing an undertaking, legally and in compliance with the laws of Luxembourg, and thereafter tokenizing into legally compliant tokenized (digital) securities for distribution to permissioned Investors is a complex end-to-end transaction. This section covers the high-level details of the lifecycle of a transaction which holds true for any type of tokenized offering undertaken by Frictionless Markets.

Frictionless Protocol: Basic Token Lifecycle
  1. Establishment of the correct Luxembourg securitization structure.

    1. The Frictionless Markets team will create the PPM (private placement memorandum) and the Final Terms for the securitization undertaking.

    2. The Frictionless Markets team creates the compartment, bank accounts of the compartment and the permissioning/provisioning of the necessary wallet infrastructure to execute the tokenization.

    3. All relevant statutory reporting and regulatory obligations for the structure are handled by the Frictionless Markets team, including AML6, SARs, CRS, FATCA, FATF, ManCo Reporting, etc.

  2. Tokenization of the undertakings.

    1. The Manager is permissioned on the Frictionless protocol.

    2. Managers can onboard Investors via subscriptions or subscription contracts to the tokenized fund/note in accordance with MiFID II regulation.

  3. Distribution of the tokenized securities.

    1. Managers can onboard Investors directly or link into permissioned distribution agents on the Frictionless protocol to distribute their tokenized securities on a global basis.

    2. Capital Calls* automatically execute upon Investors' subscriptions to a fund/funds, converting FIAT contributions to Frictionless Deposit Tokens and releasing Frictionless Digital Securities to record the transaction on-chain.

Frictionless FX Swaps

circle-check

Frictionless FX Swaps enable Investors to invest instantly, securely and risk-free at super low cost in multiple currencies.

The FX Swap contracts in the Frictionless protocol provide an instant/atomic swap of a currency pair at a quoted spot or forward rate.

Built on cash custody with G-SIB banking providers and FX partners in the EU, the list of supported currencies and currency pairs is maintained in our Frictionless Institutional Deposit Tokens listing.

circle-info

Frictionless FX Swaps remove the complexity of investing in multi-currency, whilst providing ultimate flexibility and transparency of FX rates and settlement.

FX Swaps work by automating the treasury operations in an FX transaction, namely:

  1. Establishment of optional FX fees to be paid by the seller of currency A,

  2. Utilization of the buying rate for currency Z in the swap. The rate utilized in the Frictionless protocol is obtained from our FX partners, the Frictionless Markets team support both spot and forward rates for FX Swaps offering clients the ultimate flexibility and transparency in FX swaps.

An example of a live FX Swap on the Avalanche C-Chain is at .

In this FX Swap USD was sold for 5,000 EUR. The rate used was a spot rate provided to the Frictionless Markets team. In the block explorer, you can see the collection of fees, burn of fsUSD and mint of fsEUR. The swap and fee collection ran as a single atomic transaction and cost 0.80 USD to execute on the Avalanche C-Chain.

ERC20 Swaps

ERC20 Swaps were designed by the developers in the Frictionless protocol to risk off permissionless stablecoins such as USDC or USDT.

Permissionless are a great innovation from the crypto markets which were designed for permissionless crypto referencing to US Dollars, however handling stablecoins for traditional institutional partners is still a risky proposition.

circle-check

Using the ERC20 Converter contracts, FrictionlessFundDepositTokens can be converted to/from stablecoins using the Frictionless protocol to help Managers accept stablecoins whilst off-loading their associated risks, such as de-peg events, underlying community bank reliance and liquidity risks.

Automated Fee Collection

The Frictionless protocol is designed to automate cash operations across the lifecycle of a fund, part of this automation is the collection of contracted fee structures within a fund, such as management and/or performance fees.

circle-info

The smart contracts for securities exchange, transfer, ERC20 swap and FX swaps may be programmed to automatically collect fees for Managers, opening new revenue streams for Managers whilst ensuring the visibility of fees for Investors and Managers alike.

The following diagram illustrates the design of the fee module, which enables the definition of fees to be automatically collected by a defined fee recipient during any of the value exchange functions in the protocol.

Execution of the swap as a single atomic transaction whereby currency A and currency Z are burned and minted from/to two counterparties with the automatic collection of optional fees. This operation can only be directed by the PROTOCOL_TREASURY to avoid market manipulation of FX rates.
https://snowtrace.io/tx/0x115570645b70ac573e9ce2f2d4e03f0bd71f502e4dd7019bab6a155417138851?chainId=43114arrow-up-right
Schematic a Frictionless FX Swap
Live FX Swap - fsUSD for fsEUR (spot rate from Alpha FX)
Cash Distributions
  • Portfolio Compositions

  • The Manager can issue notes, and capital calls*, and run cash distributions** from the Frictionless Markets UI, via integration with the Frictionless Markets API or directly via the smart contracts.

    Cash Distributions ** automatically distribute income and return of the underlying to the Investors, settling the Frictionless Digital Securities with Frictionless Deposit Tokens, thereafter handling the FIAT settlement in the securitization transaction.

    permissioned & transferrable digital security
    exchange
    swap
    swap
    permissioning
    circle-info

    The PROTOCOL_TREASURY manages the on/off ramp of the ERC20 stablecoin, such as USDC/USDT within its fund structures of FRICTIONLESS MARKETS SECURITIES FT.

    circle-check

    The availability of a valid configured ERC20 token for conversion to/from FrictionlessFundDepositToken along with the associated fees is transparent, any market participant may query the smart contract.

    The principle of an ERC20 Swap is simple.

    Schematic of a Frictionless ERC20 (USDC stablecoin) Swap
    1. The PROTOCOL_ADMIN defines the valid token pairs which are convertible on a 1:1 basis.

    2. Fees can be optionally defined for the conversion to/from the ERC20 token.

    3. The holder (Investor) of ERC20 tokens invokes the convertFromERC20function of the smart contract, the ERC20 tokens are sent to the PROTOCOL_TREASURY and a matching amount of FrictionlessFundDepositToken is minted and sent to the holder (Investor).

    4. If the Investor wishes to convert their FrictionlessFundDepositToken to a valid configured ERC20 token, such as USDC/USDT, then they can invoke the convertToERC20function of the smart contract. In this case, the PROTOCOL_TREASURY will receive the FrictionlessFundDepositToken and burn it, transferring the matching amount of ERC20 (less any fees) to the Investor.

    An example of two live ERC20 swaps on the Avalanche C-Chain are;

    • USDC swapped for fsUSD arrow-up-right

    • fsUSD swapped for USDC arrow-up-right

    In these swaps, you can observe the collection of optional fees and the atomic settlement of the swap of the fsUSD tokens with USDC into the PROTOCOL_TREASURY.

    Frictionless ERC20 Swap - USDC for fsUSD with automatic fee collection
    Frictionless ERC20 Swap - fsUSDC for USDC with no fee collection

    Arctitecture of the Frictionless Fee Module

    Fees may be configured to be collected in the following transactions:

    1. P2P (bi-lateral) transfer of tokens between permissioned counterparties, for example, a direct transfer of securities between two Investors, such as a secondary trade.

    2. Exchange of securities, executed by the protocol during a primary issuance, in the form of management fees upon committed capital or deployed capital.

    3. Settlement of securities, executed by the protocol or by the Investor.

    4. Conversion of an ERC20 token to/from a FrictionlessFundDepositToken, for example, converting USDC to the USD equivalent FrictionlessFundDepositToken or conversion of another ERC20 collateral.

    5. FX swap of FrictionlessFundDepositToken of different currencies.

    The fee architecture permissions the protocol admin to establish fees, this ensures that the market integrity for fees is maintained, for example, the FX rates are taken from our FX partner's spot and forward rates quoted, and the conversion of ERC20 stablecoins such as USDC and USDT to it's USD equivalent FrictionlessFundDepositToken.

    AbstractFeeModule

    Git Sourcearrow-up-right

    Inherits: IAbstractFeeModule

    Copyright © 2023 DEFYCA Labs S.à.r.l Permission is hereby granted, free of charge, to any person obtaining a copy of the Frictionless protocol smart contracts (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL DEFYCA LABS S.à.r.l BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

    hashtag
    State Variables

    hashtag
    ZERO_FEES_IN_BPS

    Use SafeERC20 for any ERC20 token in the conversion

    represents 0 bps in fees (the minima of fees or 0%)

    hashtag
    MAX_FEES_IN_BPS

    represents 10000 bps in fees (the maxima of fees or 100%)

    hashtag
    _feesInfo

    hashtag
    Functions

    hashtag
    getFeeInfo

    hashtag
    getFeeInBps

    hashtag
    getFeeRecipient

    hashtag
    calculateFeeAmount

    hashtag
    _setTokenFee

    Shouldnt arrise due to validation, but being doubly sure, we can't compute incorrect fees.

    hashtag
    _transferFees

    hashtag
    _validateFeeInfo

    Validates the FeeInfo, specifically validates the non zero address of the feeRecipientAddr and the range for the feeInBps (0 to MAX_FEES_IN_BPS).

    Parameters

    Name
    Type
    Description

    IFrictionlessDigitalSecurityToken

    Inherits: IBasicFrictionlessToken

    Author: DEFYCA Labs S.à.r.l

    Copyright © 2023 DEFYCA Labs S.à.r.l Permission is hereby granted, free of charge, to any person obtaining a copy of the Frictionless protocol smart contracts (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL DEFYCA LABS S.à.r.l BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

    feeInfo_

    FeeInfo

    the FeeInfo to validate. throws AbstractFeeModuleInvalidFeeRecipient if the feeRecipientAddr is a zero address throws AbstractFeeModuleInvalidFee if the feeInBps is not in the valid range (ZERO_FEES_IN_BPS to MAX_FEES_IN_BPS)

    This is the permissioned & transferable digital security which represents the future cash flow from the FrictionlessOnChainAssetToken and is purchased by the Investor using FrictionlessFundDepositTokens. These digital securities are permissioned and transferable between permissioned Investors in a permissioned secondary market. This token is linked to the FrictionlessOnChainAssetToken and denominated in a FIAT currency at a future date for settlement.

    hashtag
    Functions

    hashtag
    setInitData

    Sets the immutable data for the FrictionlessDigitalSecurityToken

    Parameters

    Name
    Type
    Description

    initData

    FDSImmutableData

    the immutable data for the FrictionlessDigitalSecurityToken

    hashtag
    setUpdateData

    Sets the updatable data for the FrictionlessDigitalSecurityToken

    Parameters

    Name
    Type
    Description

    mutableData

    FDSMutableData

    the updatable data for the FrictionlessDigitalSecurityToken

    hashtag
    getCurrency

    Get the baseCurrency is the FIAT denomination of the digital security, this is the currency the FrictionlessOnChainAssetToken is issued in.

    Returns

    Name
    Type
    Description

    <none>

    string

    the baseCurrency is the FIAT denomination of the digital security, this is the currency the FrictionlessOnChainAssetToken is issued in.

    hashtag
    getTokenType

    Get the type of the token as defined in the enum FrictionlessDigitalSecurityTokenType.

    Returns

    Name
    Type
    Description

    <none>

    FrictionlessDigitalSecurityTokenType

    the type of the token as defined in the enum.

    hashtag
    getOnChainAssetAddress

    Get the onChainAssetAddress the address of the FrictionlessOnChainAssetToken for which this token is a future cash distribution.

    Returns

    Name
    Type
    Description

    <none>

    address

    onChainAssetAddress the address of the FrictionlessOnChainAssetToken for which this token is a future cash distribution.

    hashtag
    getMaturesOn

    Get the maturity date of the digital security.

    Returns

    Name
    Type
    Description

    <none>

    uint256

    the maturity date of the digital security.

    hashtag
    Errors

    hashtag
    FrictionlessDigitalSecurityTokenInitDataHasAlreadyBeenSet

    error throw if there is an attempt to modify the immutable data.

    hashtag
    Structs

    hashtag
    FDSImmutableData

    Struct which represents the immutable data in the Token. Once set it cannot be modified.

    hashtag
    FDSMutableData

    Struct which represents the updatable data in the Token. This data can be modified by the Agent only.

    hashtag
    Enums

    hashtag
    FrictionlessDigitalSecurityTokenType

    Git Sourcearrow-up-right
    uint256 public constant ZERO_FEES_IN_BPS = 0;
    uint256 public constant MAX_FEES_IN_BPS = 10000;
    mapping(bytes32 => FeeInfo) private _feesInfo;
    function getFeeInfo(bytes32 tokenFeeKey_) public view override returns (FeeInfo memory);
    function getFeeInBps(bytes32 tokenFeeKey_) public view override returns (uint256);
    function getFeeRecipient(bytes32 tokenFeeKey_) public view override returns (address);
    function calculateFeeAmount(uint256 tokensAmount_, uint256 feeInBps_)
        public
        pure
        override
        returns (uint256 feeAmount_);
    function _setTokenFee(bytes32 feeKey_, FeeInfo memory feeInfo_) internal;
    function _transferFees(bytes32 feeKey_, IERC20 token_, address tokenSender_, uint256 tokensAmount_)
        internal
        returns (uint256);
    function _validateFeeInfo(FeeInfo memory feeInfo_) internal pure;
    function setInitData(FDSImmutableData calldata initData) external;
    function setUpdateData(FDSMutableData calldata mutableData) external;
    function getCurrency() external view returns (string memory);
    function getTokenType() external view returns (FrictionlessDigitalSecurityTokenType);
    function getOnChainAssetAddress() external view returns (address);
    function getMaturesOn() external view returns (uint256);
    error FrictionlessDigitalSecurityTokenInitDataHasAlreadyBeenSet();
    struct FDSImmutableData {
        string baseCurrency;
        FrictionlessDigitalSecurityTokenType tokenType;
        address onChainAssetAddress;
    }
    struct FDSMutableData {
        uint256 maturesOn;
    }
    enum FrictionlessDigitalSecurityTokenType {
        COUPON,
        STRIP
    }

    Deployments

    The Frictionless protocol is designed and built on the Avalanche C-Chainarrow-up-right, for public-permissioned issuance, trade and settlement of private markets digital securities in compliance with the blockchain & securitization laws of Luxembourg.

    Built on Avalanche!
    circle-check

    The Avalanche C-Chainarrow-up-right network is the Frictionless Markets Treasury Chain, which means that issuances and settlement of Frictionless tokens are carried out on Avalanche.

    circle-exclamation

    Always check that the smart contracts you interact with are valid contracts issued by the Frictionless Markets Protocol Administrator.

    The PROTOCOL_ADMIN address is 0x55749224f94d79687Ba3955db2180d7C5D7D2409

    hashtag
    Deployed Contracts

    The Frictionless has deployed at the following contract addresses.

    The Frictionless protocol contracts are deployed at the following addresses on Avalanche.

    Contract Name
    Address

    IFrictionlessTokensFactory

    Author: DEFYCA Labs S.à.r.l

    Copyright © 2023 DEFYCA Labs S.à.r.l Permission is hereby granted, free of charge, to any person obtaining a copy of the Frictionless protocol smart contracts (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL DEFYCA LABS S.à.r.l BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

    Interface defining the token factory for all tokens in the Frictionless protocol.

    Institutional Deposit Tokens

    circle-check

    The attestations for Frictionless Institutional Deposit Tokens are proved by the PERMISSIONED_FUND_ACCOUNTANT (Creatrust Luxembourg) and are publicly available at

    circle-exclamation

    Always check that the smart contracts you interact with are valid contracts issued by the Frictionless Markets Protocol Administrator.

    Any other address purporting to offer the Frictionless protocol is not valid.

    If you have any queries or wish to report any suspected issues, please contact the protocol admin team via [email protected]

    FrictionlessTreasuryManager

    FrictionlessTransferManager

    FrictionlessERC20ConverterManager

    FrictionlessAttestationManager

    FrictionlessFXSwap

    FrictionlessFundDepositToken

    0xbF99d9472eC0cb97cb2bCaD5e9564f3844347604arrow-up-right

    FrictionlessOnChainAssetToken

    0x08b93133C214ad306d4e16b88b6703911b29E77farrow-up-right

    FrictionlessDigitalSecurityToken

    0xA2Db6E187b34BDfb8C1592B53Bfbe242Ae5c5728arrow-up-right

    PROTOCOL_ADMINarrow-up-right

    FrictionlessPermissionsManager

    hashtag
    Functions

    hashtag
    setTreasuryManager

    Sets the Treasury Manager to be the specified address.

    Parameters

    Name
    Type
    Description

    newTreasuryManager_

    address

    the addresses of the treasury manager to set throws FrictionlessTokensFactoryZeroAddress if the newTreasuryManager_ is a zero address

    hashtag
    deployFundDepositToken

    Deploys the FrictionlessFundDepositToken contract as a proxy

    Parameters

    Name
    Type
    Description

    tokenOwner_

    address

    The owner of the deployed contract

    baseTokenInitParams_

    BaseTokenInitParams

    the base contract data to deploy a Frictionless token contract

    initData_

    IFrictionlessFundDepositToken.FFDImmutableData

    the immutable data for the FrictionlessFundDepositToken

    Returns

    Name
    Type
    Description

    tokenProxyAddr_

    address

    the address of the deployed token contract FrictionlessFundDepositToken throws FrictionlessTokensFactoryNotATreasuryManager if the msg.sender is not the treasury manager emits FrictionlessTokenDeployed event upon successful deployment of the token contract.

    hashtag
    deployDigitalSecurityToken

    Deploys the FrictionlessDigitalSecurityToken contract as a proxy

    Parameters

    Name
    Type
    Description

    tokenOwner_

    address

    The owner of the deployed contract

    baseTokenInitParams_

    BaseTokenInitParams

    the base contract data to deploy a Frictionless token contract

    initData_

    IFrictionlessDigitalSecurityToken.FDSImmutableData

    the immutable data for the FrictionlessDigitalSecurityToken

    Returns

    Name
    Type
    Description

    tokenProxyAddr_

    address

    the address of the deployed token contract FrictionlessDigitalSecurityToken throws FrictionlessTokensFactoryNotATreasuryManager if the msg.sender is not the treasury manager emits FrictionlessTokenDeployed event upon successful deployment of the token contract.

    hashtag
    deployOnChainAssetToken

    Deploys the FrictionlessOnChainAssetToken contract as a proxy

    Parameters

    Name
    Type
    Description

    tokenOwner_

    address

    The owner of the deployed contract

    baseTokenInitParams_

    BaseTokenInitParams

    the base contract data to deploy a Frictionless token contract

    specData_

    IFrictionlessOnChainAssetToken.FOCASpecData

    the immutable specification data for the FrictionlessOnChainAssetToken

    Returns

    Name
    Type
    Description

    tokenProxyAddr_

    address

    the address of the deployed token contract FrictionlessOnChainAssetToken throws FrictionlessTokensFactoryNotATreasuryManager if the msg.sender is not the treasury manager emits FrictionlessTokenDeployed event upon successful deployment of the token contract.

    hashtag
    treasuryManager

    returns the address of the treasuryManager

    Returns

    Name
    Type
    Description

    <none>

    address

    the address of the treasuryManager

    hashtag
    existingFrictionlessTokens

    Checks whether a given token address is an existing frictionless token

    Parameters

    Name
    Type
    Description

    tokenAddr_

    address

    the address of the token to check

    Returns

    Name
    Type
    Description

    <none>

    bool

    A boolean indicating whether the token is an existing frictionless token

    hashtag
    Events

    hashtag
    FrictionlessTokenDeployed

    Event emitted upon successful deployment of a compliance contract.

    hashtag
    Errors

    hashtag
    FrictionlessTokensFactoryZeroAddress

    error thrown if an attempt to set a zero address contract during function setTreasuryManager

    hashtag
    FrictionlessTokensFactoryNotATreasuryManager

    error thrown if the msg.sender is not the treasury manager during the functions deployFundDepositToken, deployDigitalSecurityToken, or deployOnChainAssetToken

    hashtag
    Structs

    hashtag
    BaseTokenInitParams

    Struct to represent the base contract data to deploy a Frictionless token contract.

    Git Sourcearrow-up-right

    The PROTOCOL_ADMIN address is 0x55749224f94d79687Ba3955db2180d7C5D7D2409

    Any other address purporting to offer the Frictionless protocol is not valid.

    If you have any queries or wish to report any suspected issues, please contact the protocol admin team via [email protected]

    hashtag
    Deployed Institutional Deposit Tokens

    The Frictionless PROTOCOL_ADMINarrow-up-right has deployed the following FrictionlessFundDepositTokens.

    The Frictionless Institutional Deposit Tokens are deployed at the following token addresses on Avalanche.

    Currency
    Frictionless Token Address

    USD

    EUR

    hashtag
    Structure of Frictionless Institutional Deposit Tokens

    The Frictionless Institutional Deposit Token (FricitonlessFundDepositToken) is designed as a method of recording a FIAT contribution for a PERMISSIONED_INVESTOR into a listed fund on the Frictionless protocol.

    triangle-exclamation

    Neither Frictionless Markets nor its parent company DEFYA HOLDINGS nor any subsidiaries actively manage currency contributions for Investors or permissioned participants in the protocol. All investment decisions must made exclusively by Investors or their appointed wealth advisors or agents.

    The Frictionless Markets team passively manages a collection of open-ended fund structures which are designed to securitise the currency contributions, so thereafter these tokens can be used to record payment, settlement and trade in tokenized securities from funds listed on the Frictionless protocol.

    The following high-level diagram describes the main participants and their high-level interaction with the protocol.

    Passive Securitization Structure of Frictionless Institutional Deposit Tokens
    circle-info

    For more information on the legal structure of the FRICTIONLESS MARKETS SECURITIES FT, consult our legal & fund documentationarrow-up-right

    https://snowtrace.io/address/0x143F369d362E6F9Bb2b9282c48e55d19f5EB5305arrow-up-right

    IFrictionlessOnChainAssetToken

    Inherits: IBasicFrictionlessToken

    Author: DEFYCA Labs S.à.r.l

    Copyright © 2023 DEFYCA Labs S.à.r.l Permission is hereby granted, free of charge, to any person obtaining a copy of the Frictionless protocol smart contracts (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL DEFYCA LABS S.à.r.l BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

    IAbstractFeeModule

    Author: DEFYCA Labs S.à.r.l

    Copyright © 2023 DEFYCA Labs S.à.r.l Permission is hereby granted, free of charge, to any person obtaining a copy of the Frictionless protocol smart contracts (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL DEFYCA LABS S.à.r.l BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

    function setTreasuryManager(address newTreasuryManager_) external;
    function deployFundDepositToken(
        address tokenOwner_,
        BaseTokenInitParams calldata baseTokenInitParams_,
        IFrictionlessFundDepositToken.FFDImmutableData calldata initData_
    ) external returns (address tokenProxyAddr_);
    function deployDigitalSecurityToken(
        address tokenOwner_,
        BaseTokenInitParams calldata baseTokenInitParams_,
        IFrictionlessDigitalSecurityToken.FDSImmutableData calldata initData_,
        IFrictionlessDigitalSecurityToken.FDSMutableData calldata updateData_
    ) external returns (address tokenProxyAddr_);
    function deployOnChainAssetToken(
        address tokenOwner_,
        BaseTokenInitParams calldata baseTokenInitParams_,
        IFrictionlessOnChainAssetToken.FOCASpecData calldata specData_,
        IFrictionlessOnChainAssetToken.FOCAIssuanceData calldata issuanceData_,
        IFrictionlessOnChainAssetToken.FOCAUpdateData calldata updateData_
    ) external returns (address tokenProxyAddr_);
    function treasuryManager() external view returns (address);
    function existingFrictionlessTokens(address tokenAddr_) external view returns (bool);
    event FrictionlessTokenDeployed(
        IBasicFrictionlessToken.FrictionlessTokenTypes indexed tokenType, address newTokenContract
    );
    error FrictionlessTokensFactoryZeroAddress();
    error FrictionlessTokensFactoryNotATreasuryManager(address);
    struct BaseTokenInitParams {
        address implementationAuthority;
        address identityRegistry;
        address compliance;
        address onChainId;
        string tokenName;
        string tokenSymbol;
    }

    updateData_

    IFrictionlessDigitalSecurityToken.FDSMutableData

    the mutable data for the FrictionlessDigitalSecurityToken

    issuanceData_

    IFrictionlessOnChainAssetToken.FOCAIssuanceData

    the immutable issuance data for the FrictionlessOnChainAssetToken

    updateData_

    IFrictionlessOnChainAssetToken.FOCAUpdateData

    the mutable update data for the FrictionlessOnChainAssetToken

    0x684759399AC55804603CB84A9210686B52f4A627arrow-up-right
    0xD6bf0870C69a23d0f25238Dba7DBF112Afbef344arrow-up-right
    0xB07DDDcB7501Da7064adC68aDc5533d9C41033dCarrow-up-right
    0xb33a34Cef89398195739ad5566B314F6A50FE233arrow-up-right
    0x143F369d362E6F9Bb2b9282c48e55d19f5EB5305arrow-up-right
    0xA6dE189d26428A285c0d56dfCaFF8E11F664B9fCarrow-up-right
    Implementation of the storage of the underlying OnChain Asset and it's data.

    hashtag
    Functions

    hashtag
    setSpecificationData

    Sets the specData data for the FrictionlessOnChainAssetToken. throws FrictionlessOnChainAssetTokenUnableToUpdateData This data is immutable, an attempt to modify will generate the error FrictionlessOnChainAssetTokenUnableToUpdateData

    Parameters

    Name
    Type
    Description

    specData

    FOCASpecData

    the specData data for the FrictionlessOnChainAssetToken

    hashtag
    setIssuanceData

    Sets the issuanceData data for the FrictionlessOnChainAssetToken throws FrictionlessOnChainAssetTokenUnableToUpdateData This data is immutable, an attempt to modify will generate the error FrictionlessOnChainAssetTokenUnableToUpdateData

    Parameters

    Name
    Type
    Description

    issuanceData

    FOCAIssuanceData

    the updatable data for the FrictionlessOnChainAssetToken

    hashtag
    setUpdateData

    Sets the updatable data for the FrictionlessOnChainAssetToken

    Parameters

    Name
    Type
    Description

    updateData

    FOCAUpdateData

    the updatable data for the FrictionlessOnChainAssetToken

    hashtag
    getSpecificationData

    Get the specData data for the FrictionlessOnChainAssetToken.

    Returns

    Name
    Type
    Description

    <none>

    FOCASpecData

    the specData data for the FrictionlessOnChainAssetToken

    hashtag
    getIssuanceData

    Get the issuanceData data for the FrictionlessOnChainAssetToken.

    Returns

    Name
    Type
    Description

    <none>

    FOCAIssuanceData

    the issuanceData data for the FrictionlessOnChainAssetToken

    hashtag
    getUpdateData

    Get the updateData data for the FrictionlessOnChainAssetToken.

    Returns

    Name
    Type
    Description

    <none>

    FOCAUpdateData

    the updateData data for the FrictionlessOnChainAssetToken

    hashtag
    getCurrency

    Get the currency the FrictionlessOnChainAssetToken is issued in.

    Returns

    Name
    Type
    Description

    <none>

    string

    the currency the FrictionlessOnChainAssetToken is issued in.

    hashtag
    Errors

    hashtag
    FrictionlessOnChainAssetTokenUnableToUpdateData

    error throw if there is an attempt to modify the immutable data.

    hashtag
    Structs

    hashtag
    FOCASpecData

    The specification data for the FrictionlessOnChainAssetToken, this is an immutable data struct.

    hashtag
    FOCAIssuanceData

    The issuance data for the FrictionlessOnChainAssetToken, this is an immutable data struct.

    hashtag
    FOCAUpdateData

    The uopdatable data for the FrictionlessOnChainAssetToken.

    hashtag
    Enums

    hashtag
    FrictionlessOnChainAssetSchedule

    Enum for the schedule of the payments by the Manager, either pro_rat or coupon/bullet style.

    hashtag
    FrictionlessOnChainAssetPaymentFrequency

    Enum for the periodicity of payments by the Manager

    hashtag
    FrictionlessOnChainAssetYieldType

    Enum for the yield for this FrictionlessOnChainAssetToken is a fixed/floating rate

    hashtag
    FrictionlessOnChainAssetPriceStatus

    Enum for the price quote status obtained at auction

    hashtag
    FrictionlessOnChainAssetStatus

    Enum for the current status of the FrictionlessOnChainAssetToken. Updated over time by the Treasury

    hashtag
    FrictionlessOnChainAssetRiskGrade

    Enum for the current S&P style riskGrade of the FrictionlessOnChainAssetToken. Updated over time by the Manager/Treasury/Risk Oracle.

    Git Sourcearrow-up-right
    hashtag
    Functions

    hashtag
    getFeeInfo

    get the FeeInfo for a given key.

    Parameters

    Name
    Type
    Description

    feeKey_

    bytes32

    the key as generated by the function getTokenFeeKey

    Returns

    Name
    Type
    Description

    <none>

    FeeInfo

    FeeInfo the fees associated with a token transfer.

    hashtag
    getFeeInBps

    get the feeInBps value for a given key

    Parameters

    Name
    Type
    Description

    tokenFeeKey_

    bytes32

    the key as generated by the function getTokenFeeKey

    Returns

    Name
    Type
    Description

    <none>

    uint256

    the feeInBps value

    hashtag
    getFeeRecipient

    get the feeRecipientAddr value for a given key

    Parameters

    Name
    Type
    Description

    tokenFeeKey_

    bytes32

    the key as generated by the function getTokenFeeKey

    Returns

    Name
    Type
    Description

    <none>

    address

    the feeRecipientAddr value

    hashtag
    calculateFeeAmount

    Calculates the actual fee in absolute terms for a given fee in basis points.

    Parameters

    Name
    Type
    Description

    tokensAmount_

    uint256

    the amount of tokens used to determine the base calculation.

    feeInBps_

    uint256

    the fee in basis points for calculation.

    Returns

    Name
    Type
    Description

    feeAmount_

    uint256

    the actual fee in absolute terms for a given fee in basis points.

    hashtag
    Events

    hashtag
    FrictionlessFeeSet

    Event emitted during _setTokenFee

    hashtag
    Errors

    hashtag
    AbstractFeeModuleInvalidFeeRecipient

    error thrown if the recipient is a zero address

    hashtag
    AbstractFeeModuleInvalidFee

    error thrown if the feesInBps is outside the valid range

    hashtag
    Structs

    hashtag
    FeeInfo

    Struct which defines the FeeInfo, representing the fee in basis points and the recipient of the fees on-chain.

    Git Sourcearrow-up-right
    function setSpecificationData(FOCASpecData calldata specData) external;
    function setIssuanceData(FOCAIssuanceData calldata issuanceData) external;
    function setUpdateData(FOCAUpdateData calldata updateData) external;
    function getSpecificationData() external view returns (FOCASpecData memory);
    function getIssuanceData() external view returns (FOCAIssuanceData memory);
    function getUpdateData() external view returns (FOCAUpdateData memory);
    function getCurrency() external view returns (string memory);
    error FrictionlessOnChainAssetTokenUnableToUpdateData();
    struct FOCASpecData {
        uint256 issuedOn;
        uint256 maturityDays;
        FrictionlessOnChainAssetSchedule schedule;
        FrictionlessOnChainAssetPaymentFrequency paymentFrequency;
        FrictionlessOnChainAssetYieldType yieldType;
        string baseCurrency;
        uint256 stripTotal;
        string name;
        string symbol;
    }
    struct FOCAIssuanceData {
        uint256 auctionedOn;
        FrictionlessOnChainAssetPriceStatus priceQuoteStatus;
        string onChainAssetUUID;
        string issuerUUID;
        string isin;
        string issuanceDocs;
        string assetClass;
    }
    struct FOCAUpdateData {
        uint256 maturesOn;
        uint256 total;
        FrictionlessOnChainAssetStatus status;
        uint256 yield;
        FrictionlessOnChainAssetRiskGrade riskGrade;
        uint256 pullToParValue;
        address custodianAddress;
    }
    enum FrictionlessOnChainAssetSchedule {
        SCHEDULE_COUPON_ONLY,
        SCHEDULE_PRO_RATA
    }
    enum FrictionlessOnChainAssetPaymentFrequency {
        PAYMENT_FREQUENCY_DAILY,
        PAYMENT_FREQUENCY_WEEKLY,
        PAYMENT_FREQUENCY_MONTHLY,
        PAYMENT_FREQUENCY_QUARTERLY,
        PAYMENT_FREQUENCY_SEMI_ANNUALLY,
        PAYMENT_FREQUENCY_ANNUALLY,
        PAYMENT_FREQUENCY_SINGLE
    }
    enum FrictionlessOnChainAssetYieldType {
        YIELD_FIXED,
        YIELD_FLOATING
    }
    enum FrictionlessOnChainAssetPriceStatus {
        PRICE_QUOTE_STATUS_UNDER_SUBSCRIBED,
        PRICE_QUOTE_STATUS_PRICED_AT_PAR,
        PRICE_QUOTE_STATUS_PRICED_AT_DISCOUNT,
        PRICE_QUOTE_STATUS_PRICED_AT_PREMIUM
    }
    enum FrictionlessOnChainAssetStatus {
        STATUS_MINTED,
        STATUS_PURCHASED,
        STATUS_MATURED,
        STATUS_IMPAIRED,
        STATUS_REDEEMED
    }
    enum FrictionlessOnChainAssetRiskGrade {
        BER_AAA,
        BER_AA,
        BER_A,
        BER_BBB,
        BER_BB,
        BER_B,
        BER_CCC,
        BER_CC,
        BER_C,
        BER_D,
        BER_UNRATED
    }
    function getFeeInfo(bytes32 feeKey_) external view returns (FeeInfo memory);
    function getFeeInBps(bytes32 tokenFeeKey_) external view returns (uint256);
    function getFeeRecipient(bytes32 tokenFeeKey_) external view returns (address);
    function calculateFeeAmount(uint256 tokensAmount_, uint256 feeInBps_) external pure returns (uint256 feeAmount_);
    event FrictionlessFeeSet(bytes32 indexed feeKey, FeeInfo feeInfo);
    error AbstractFeeModuleInvalidFeeRecipient();
    error AbstractFeeModuleInvalidFee(uint256 feeInBps);
    struct FeeInfo {
        uint256 feeInBps;
        address feeRecipientAddr;
    }

    GBP

    Frictionless Bristish Pound Sterling - fsGBParrow-up-right

    CHF

    Frictionless Swisss Franc - fsCHFarrow-up-right

    HKD

    Frictionless Hong Kong Dollar - fsHKDarrow-up-right

    SGD

    Frictionless Signapore Dollar - fsSGDarrow-up-right

    JPY

    Frictionless Japanese Yen - fsJPYarrow-up-right

    AED

    Frictionless Emirati Dirham - fsAEDarrow-up-right

    Frictionless U.S. Dollar - fsUSDarrow-up-right
    Frictionless Euro - fsEURarrow-up-right

    IFrictionlessComplianceModule

    Git Sourcearrow-up-right

    Inherits: IModule

    Author: DEFYCA Labs S.à.r.l

    Copyright © 2023 DEFYCA Labs S.à.r.l Permission is hereby granted, free of charge, to any person obtaining a copy of the Frictionless protocol smart contracts (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL DEFYCA LABS S.à.r.l BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

    The IFrictionlessCompliance is responsible for the compliant transfer of the various Tokens in the Frictionless protocol.

    hashtag
    Functions

    hashtag
    setPermissionsManager

    Sets the instance of the IFrictionlessPermissionsManager to determine permissions for users.

    Parameters

    Name
    Type
    Description

    hashtag
    setComplianceFactory

    Sets the instance of the IFrictionlessComplianceFactory to determine the compliance module for the protocol.

    Parameters

    Name
    Type
    Description

    hashtag
    permissionsManager

    Gets the instance of the IFrictionlessPermissionsManager to determine permissions for users.

    Returns

    Name
    Type
    Description

    hashtag
    complianceFactory

    Gets the instance of the IFrictionlessComplianceFactory to determine the compliance module for the protocol.

    Returns

    Name
    Type
    Description

    hashtag
    isTreasury

    Verifies if the specified wallet address is a PROTOCOL_TREASURY user.

    Parameters

    Name
    Type
    Description

    Returns

    Name
    Type
    Description

    hashtag
    isCustodian

    Verifies if the specified wallet address is a PERMISSIONED_CUSTODIAN user.

    Parameters

    Name
    Type
    Description

    Returns

    Name
    Type
    Description

    hashtag
    isInvestor

    Verifies if the specified wallet address is a PERMISSIONED_INVESTOR user.

    Parameters

    Name
    Type
    Description

    Returns

    Name
    Type
    Description

    hashtag
    isManager

    Verifies if the specified wallet address is a PERMISSIONED_MANAGER user.

    Parameters

    Name
    Type
    Description

    Returns

    Name
    Type
    Description

    hashtag
    isCalculatingAgent

    Verifies if the specified wallet address is a PERMISSIONED_CALCULATING_AGENT user.

    Parameters

    Name
    Type
    Description

    Returns

    Name
    Type
    Description

    hashtag
    isTransferAgent

    Verifies if the specified wallet address is a PERMISSIONED_TRANSFER_AGENT user.

    Parameters

    Name
    Type
    Description

    Returns

    Name
    Type
    Description

    hashtag
    isFundAccountant

    Verifies if the specified wallet address is a PERMISSIONED_FUND_ACCOUNTANT user.

    Parameters

    Name
    Type
    Description

    Returns

    Name
    Type
    Description

    hashtag
    isUser

    Verifies if the specified wallet address is a permissioned user in the Frictionless protocol.

    Parameters

    Name
    Type
    Description

    Returns

    Name
    Type
    Description

    hashtag
    hasClaim

    verify if the userAddress is permissioned in the Frictionless protocol and has a valid claim

    Parameters

    Name
    Type
    Description

    Returns

    Name
    Type
    Description

    hashtag
    Events

    hashtag
    FrictionlessTokenTransferred

    Event emitted during compliance module transfers

    hashtag
    Errors

    hashtag
    FrictionlessIsZeroAddress

    throws if specific address is zero.

    hashtag
    FrictionlessComplianceModuleInvalidCompliance

    thrown if the compliance module address is invalid during bindCompliance and unBindCompliance

    hashtag
    FrictionlessComplianceModuleNotAnApprovedCompliance

    thrown if the compliance module address is not approved during bindCompliance

    hashtag
    FrictionlessComplianceModuleComplianceIsAlreadyBound

    thrown if the compliance module address is already bound, thrown by bindCompliance

    hashtag
    FrictionlessComplianceModuleNotABoundCompliance

    thrown if the compliance module address is not already bound during unBindCompliance

    frictionlessPermissionsManager_

    address

    the address of the IFrictionlessPermissionsManager contract

    newComplianceFactory_

    address

    the address of the IFrictionlessComplianceFactory contract

    <none>

    IFrictionlessPermissionsManager

    the address of the IFrictionlessPermissionsManager contract

    <none>

    IFrictionlessComplianceFactory

    the address of the IFrictionlessComplianceFactory contract

    walletAddress_

    address

    the address of the users wallet.

    <none>

    bool

    true if the specified wallet address is a PROTOCOL_TREASURY user, otherwise false

    walletAddress_

    address

    the address of the users wallet.

    <none>

    bool

    true if the specified wallet address is a PERMISSIONED_CUSTODIAN user, otherwise false

    walletAddress_

    address

    the address of the users wallet.

    <none>

    bool

    true if the specified wallet address is a PERMISSIONED_INVESTOR user, otherwise false

    walletAddress_

    address

    the address of the users wallet.

    <none>

    bool

    true if the specified wallet address is a PERMISSIONED_MANAGER user, otherwise false

    walletAddress_

    address

    the address of the users wallet.

    <none>

    bool

    true if the specified wallet address is a PERMISSIONED_CALCULATING_AGENT user, otherwise false

    walletAddress_

    address

    the address of the users wallet.

    <none>

    bool

    true if the specified wallet address is a PERMISSIONED_TRANSFER_AGENT user, otherwise false

    walletAddress_

    address

    the address of the users wallet.

    <none>

    bool

    true if the specified wallet address is a PERMISSIONED_FUND_ACCOUNTANT user, otherwise false

    walletAddress_

    address

    the address of the users wallet.

    <none>

    bool

    true if the specified wallet address is a permissioned user in the Frictionless protocol, otherwise false

    userAddress_

    address

    the address of the user's wallet to verify

    userType_

    IFrictionlessPermissionsManager.FrictionlessPermissionedUser

    the type of the user as per the enum

    <none>

    bool

    true if a valid permissioned user and has a valid claim, otherwise false.

    function setPermissionsManager(address frictionlessPermissionsManager_) external;
    function setComplianceFactory(address newComplianceFactory_) external;
    function permissionsManager() external view returns (IFrictionlessPermissionsManager);
    function complianceFactory() external view returns (IFrictionlessComplianceFactory);
    function isTreasury(address walletAddress_) external view returns (bool);
    function isCustodian(address walletAddress_) external view returns (bool);
    function isInvestor(address walletAddress_) external view returns (bool);
    function isManager(address walletAddress_) external view returns (bool);
    function isCalculatingAgent(address walletAddress_) external view returns (bool);
    function isTransferAgent(address walletAddress_) external view returns (bool);
    function isFundAccountant(address walletAddress_) external view returns (bool);
    function isUser(address walletAddress_) external view returns (bool);
    function hasClaim(address userAddress_, IFrictionlessPermissionsManager.FrictionlessPermissionedUser userType_)
        external
        view
        returns (bool);
    event FrictionlessTokenTransferred(
        IBasicFrictionlessToken.FrictionlessTokenTypes tokenType,
        address tokenAddr,
        address from,
        address to,
        uint256 amount
    );
    error FrictionlessIsZeroAddress(string);
    error FrictionlessComplianceModuleInvalidCompliance(address compliance);
    error FrictionlessComplianceModuleNotAnApprovedCompliance(address compliance);
    error FrictionlessComplianceModuleComplianceIsAlreadyBound(address compliance);
    error FrictionlessComplianceModuleNotABoundCompliance(address compliance);

    IFrictionlessModularCompliance

    Git Sourcearrow-up-right

    Inherits: IModularCompliance

    Author: DEFYCA Labs S.à.r.l

    Copyright © 2023 DEFYCA Labs S.à.r.l Permission is hereby granted, free of charge, to any person obtaining a copy of the Frictionless protocol smart contracts (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL DEFYCA LABS S.à.r.l BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

    The IFrictionlessModularCompliance is responsible for the compliant transfer of the various Tokens in the Frictionless protocol.

    hashtag
    Functions

    hashtag
    init

    Initializes the modular compliance, sets the maximum allowable modules per token and adds the modules provided

    Parameters

    Name
    Type
    Description

    hashtag
    updateMaxModulesCount

    Set the maximum number of allowable modules which can be bound.

    Parameters

    Name
    Type
    Description

    hashtag
    addModules

    Adds modules based on the array of module addresses provided

    Parameters

    Name
    Type
    Description

    hashtag
    removeModules

    Removes modules based on the array of module addresses provided

    Parameters

    Name
    Type
    Description

    hashtag
    maxModulesCount

    Returns the maximum number of allowable modules which can be bound.

    Returns

    Name
    Type
    Description

    hashtag
    Events

    hashtag
    MaxModulesCountUpdated

    Emitted during updateMaxModulesCount to inform of new modules max count updates

    hashtag
    ModulesAdded

    Emitted during addModules to inform of new modules added

    hashtag
    ModulesRemoved

    Emitted during removeModules to inform of modules removed

    hashtag
    Errors

    hashtag
    FrictionlessIsZeroAddress

    thrown if specific address is zero.

    hashtag
    FrictionlessModularComplianceZeroMaxModulesCount

    thrown if an attempt to set the maximum number of allowable modules to zero is made in updateMaxModulesCount

    hashtag
    FrictionlessModularComplianceModuleIsAlreadyBound

    thrown if an attempt to add an already existing module during addModules

    hashtag
    FrictionlessModularComplianceModuleDoesNotExist

    thrown if module for the given address is not already bound by the modifier onlyExistingModule

    hashtag
    FrictionlessModularComplianceMaxModuleCountReached

    thrown if an attempt to add more than the allowable modules during addModules

    hashtag
    FrictionlessModularComplianceCallerNotATokenOrOwner

    thrown during bindToken or unBindToken if the caller is not the owner or the bound token address

    hashtag
    FrictionlessModularComplianceCallerNotAToken

    thrown if the the msg.sender is not the bound token address during modifier onlyToken

    Protocol Roadmap

    The Frictionless protocol is an upgradable and extensible market infrastructure. The protocol is developed by the IP company DEFYCA Labs S.à.r.l, which develops the smart contract suite under the permissive MIT license.

    circle-info

    To contribute or request features to the protocol, please consult the CONTRIBUTINGarrow-up-right documentation for the smart contract suite.

    The roadmap for the Frictionless protocol smart contracts includes:

    1. Fundamental Analysis - Using the PERMISSIONED_CALCULATING_AGENT role to provide fundamental analysis on underlying portfolios via smart contracts in privacy-protecting mode.

    2. Qualified Transfer Agents - Opening access to 3rd party transfer agents to execute the transfer and settlement of securities issued on the Frictionless protocol in accordance with local regulatory posture.

    3. Portfolio Re-Balancers - A suite of smart contracts which enable PERMISSIONED_INVESTORS to automatically re-balance their portfolio of investments according to their specific investment goals.

    The broader roadmap includes features which are commercially developed by Frictionless Markets S.à.r.l, which can be requested via the site.

    https://www.frictionless.marketsarrow-up-right

    modules_

    address[]

    the array of module addresses to be added

    maxModulesCount_

    uint256

    maximum number of allowable modules which can be bound. throws FrictionlessModularComplianceMaxModuleCountReached if the maximum amount of modules has been reached as per the maxModulesCount throws FrictionlessModularComplianceModuleIsAlreadyBound if the module is already bound throws FrictionlessIsZeroAddress if the module address is a zero address throws FrictionlessModularComplianceZeroMaxModulesCount if an attempt to set the maximum number of allowable modules to zero is made in updateMaxModulesCount emits ModulesAdded upon sucessful addition emits MaxModulesCountUpdated upon successful update of the maximum modules count.

    newMaxModulesCount_

    uint256

    maximum number of allowable modules which can be bound. throws FrictionlessModularComplianceZeroMaxModulesCount if an attempt to set the maximum number of allowable modules to zero is made in updateMaxModulesCount emits MaxModulesCountUpdated upon successful update of the maximum modules count.

    modulesToAdd_

    address[]

    the array of module addresses to be added throws FrictionlessModularComplianceMaxModuleCountReached if the maximum amount of modules has been reached as per the maxModulesCount throws FrictionlessModularComplianceModuleIsAlreadyBound if the module is already bound throws FrictionlessIsZeroAddress if the module address is a zero address emits ModulesAdded upon sucessful addition

    modulesToRemove_

    address[]

    the array of module addresses to be removed throws FrictionlessModularComplianceModuleDoesNotExist if module for the given address is not already bound emits ModulesRemoved upon sucessful removal

    <none>

    uint256

    maximum number of allowable modules which can be bound.

    function init(address[] calldata modules_, uint256 maxModulesCount_) external;
    function updateMaxModulesCount(uint256 newMaxModulesCount_) external;
    function addModules(address[] calldata modulesToAdd_) external;
    function removeModules(address[] calldata modulesToRemove_) external;
    function maxModulesCount() external view returns (uint256);
    event MaxModulesCountUpdated(uint256 newMaxModulesCount, uint256 oldMaxModulesCount);
    event ModulesAdded(address[] modules);
    event ModulesRemoved(address[] modules);
    error FrictionlessIsZeroAddress(string);
    error FrictionlessModularComplianceZeroMaxModulesCount();
    error FrictionlessModularComplianceModuleIsAlreadyBound(address module);
    error FrictionlessModularComplianceModuleDoesNotExist(address module);
    error FrictionlessModularComplianceMaxModuleCountReached();
    error FrictionlessModularComplianceCallerNotATokenOrOwner(address caller);
    error FrictionlessModularComplianceCallerNotAToken(address caller);

    IFrictionlessComplianceFactory

    Git Sourcearrow-up-right

    Author: DEFYCA Labs S.à.r.l

    Copyright © 2023 DEFYCA Labs S.à.r.l Permission is hereby granted, free of charge, to any person obtaining a copy of the Frictionless protocol smart contracts (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL DEFYCA LABS S.à.r.l BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

    Interface defining the upgradeable compliance factory for all tokens in the Frictionless protocol.

    hashtag
    Functions

    hashtag
    setTreasuryManager

    Sets the Treasury Manager to be the specified address.

    Parameters

    Name
    Type
    Description

    hashtag
    updateModularComplianceImpl

    Updates and upgrades the modular compliance implementation

    Parameters

    Name
    Type
    Description

    hashtag
    updateSupportedComplianceData

    Updates the set of supported modular compliance modules.

    Parameters

    Name
    Type
    Description

    hashtag
    updateModularComplianceData

    Updates the modular compliance data.

    Parameters

    Name
    Type
    Description

    hashtag
    deployCompliance

    Deploys the compliance contract using the ProxyBeacon with the associated FrictionlessPermissionsManager contract

    Parameters

    Name
    Type
    Description

    Returns

    Name
    Type
    Description

    hashtag
    treasuryManager

    returns the address of the treasuryManager

    Returns

    Name
    Type
    Description

    hashtag
    modularComplianceBeacon

    returns the ProxyBeacon of the ModularCompliance

    Returns

    Name
    Type
    Description

    hashtag
    getModularComplianceImpl

    returns the address of the ModularCompliance

    Returns

    Name
    Type
    Description

    hashtag
    getModularComplianceTokenType

    returns the FrictionlessTokenTypes which is bound by the ModularCompliance

    Parameters

    Name
    Type
    Description

    Returns

    Name
    Type
    Description

    hashtag
    getSupportedComplianceModulesCount

    returns the amount of supported compliances ModularCompliance for the specified tokenType_

    Parameters

    Name
    Type
    Description

    Returns

    Name
    Type
    Description

    hashtag
    getSupportedComplianceModules

    returns the array of supported compliances ModularCompliance for the specified tokenType_

    Parameters

    Name
    Type
    Description

    Returns

    Name
    Type
    Description

    hashtag
    getSupportedComplianceInfo

    hashtag
    isSupportedComplianceModule

    returns true if the compliance module supports the Frictionless token type, otherwise false

    Parameters

    Name
    Type
    Description

    Returns

    Name
    Type
    Description

    hashtag
    isModularCompliance

    Returns true if the address provided is a ModularCompliance contract

    Parameters

    Name
    Type
    Description

    Returns

    Name
    Type
    Description

    hashtag
    Events

    hashtag
    FrictionlessComplianceDeployed

    Event emitted upon successful deployment of a compliance contract.

    hashtag
    Errors

    hashtag
    FrictionlessComplianceFactoryZeroAddr

    error thrown if the specified contract address is a zero address, during init, setTreasuryManager, and updateModularComplianceImpl

    hashtag
    FrictionlessComplianceFactoryNotATreasuryManager

    error thrown if the msg.sender is not the treasury manager during the function deployCompliance

    hashtag
    FrictionlessComplianceFactoryNotAModularCompliance

    error thrown if the modular compliance is invlaid for hte token type during the function updateModularCompliancesModules

    hashtag
    FrictionlessComplianceFactoryInvalidTokenType

    error thrown if an invalid tokenType is specified during deployCompliance

    hashtag
    FrictionlessComplianceFactoryInvalidModularComplianceData

    error thrown if an invalid module is specified during updateModularCompliancesModules

    hashtag
    Structs

    hashtag
    SupportedComplianceData

    hashtag
    ModularComplianceInfo

    hashtag
    UpdateModularComplianceData

    Structure to represent the update of modular compliance data.

    hashtag
    UpdateSupportedComplianceData

    Structure to represent the update of modular compliance data for a given token type

    IFrictionlessPermissionsManager

    Git Sourcearrow-up-right

    Author: DEFYCA Labs S.à.r.l

    Copyright © 2023 DEFYCA Labs S.à.r.l Permission is hereby granted, free of charge, to any person obtaining a copy of the Frictionless protocol smart contracts (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL DEFYCA LABS S.à.r.l BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

    The IFrictionlessPermissionsManager is responsible for the management of permission of the various participants in the Frictionless protocol. The roles and responsibilities are defined in the public README for the Frictionless protocol at https://gitlab.com/dfyclabs/protocol/dfyclabs-tokens/-/blob/main/README.md?ref_type=heads#roles-responsibilities

    hashtag
    Functions

    hashtag
    isPermissioned

    Validates if a wallet address is permissioned in the Frictionless protocol

    Parameters

    Name
    Type
    Description

    Returns

    Name
    Type
    Description

    hashtag
    registerIdentity

    Registers a users wallet address as an OnChainId (Identity) to the Frictionless protocol. This Identity is used when permissioning a user to the protocol by invoking the addUser function later.

    Parameters

    Name
    Type
    Description

    Returns

    Name
    Type
    Description

    hashtag
    getIdentity

    Gets a users OnChainId (Identity) in the Frictionless protocol.

    Parameters

    Name
    Type
    Description

    Returns

    Name
    Type
    Description

    hashtag
    getClaimMsgHash

    Get the signed claimData message to be used in the addUser function. The message must be signed using the PK of the ClaimIssuer (PROTOCOL_ADMIN)

    Parameters

    Name
    Type
    Description

    Returns

    Name
    Type
    Description

    hashtag
    hasClaim

    verify if the userAddress is permissioned in the Frictionless protocol and has a valid claim

    Parameters

    Name
    Type
    Description

    Returns

    Name
    Type
    Description

    hashtag
    addUser

    Adds a user's OnChainId (Identity) to the Frictionless protocol along with its associated claim data. The Identity is created by invoking the registerIdentity function first.

    Parameters

    Name
    Type
    Description

    Returns

    Name
    Type
    Description

    hashtag
    removeUser

    Removes a user from the Frictionless protocol along with its associated claim data.

    Parameters

    Name
    Type
    Description

    Returns

    Name
    Type
    Description

    hashtag
    Events

    hashtag
    FrictionlessPermissionedUserAdded

    Emitted when a user is added to the Frictionless protocol. This event is emitted by the addUser function.

    hashtag
    FrictionlessPermissionedUserRegistered

    Emitted when a user is registered in the Frictionless protocol. This event is emitted by the registerIdentity function.

    hashtag
    FrictionlessPermissionedUserRemoved

    Emitted when a user is removed in the Frictionless protocol. This event is emitted by the removeUser function.

    hashtag
    Errors

    hashtag
    FrictionlessIsZeroAddress

    throws if specific address is zero.

    hashtag
    FrictionlessInvalidPermissionForTreasury

    throws if treasury tries to add or remove treasury.

    hashtag
    FrictionlessUserIsNotPermssionedInvestor

    throws if user is not a permissioned investor

    hashtag
    Structs

    hashtag
    Claim

    the internal struct defining a Claim for a PERMISSIONED_USER in the protocol. Used to submit claims for the OnChainId by the ClaimIssuer.

    hashtag
    Enums

    hashtag
    FrictionlessPermissionedUser

    Enum of the Frictionless protocol participants.

    newTreasuryManager_

    address

    the address of the treasury manager to set throws FrictionlessComplianceFactoryZeroAddress if the newTreasuryManager_ is a zero address

    newModularComplianceImpl_

    address

    the address of the modular compliance implementation

    updateSupportedComplianceDataArr_

    UpdateSupportedComplianceData[]

    the set of supported modular compliance modules.

    updateModularComplianceDataArr_

    UpdateModularComplianceData[]

    the modular compliance data.

    tokenType_

    IBasicFrictionlessToken.FrictionlessTokenTypes

    The Frictionless token type as defined by IBasicFrictionlessToken.FrictionlessTokenTypes

    <none>

    address

    the address of the deployed compliance contract for the specified Frictionless token type throws FrictionlessComplianceFactoryNotATreasuryManager if the msg.sender is not the treasury manager emits FrictionlessComplianceDeployed event upon successful deployment of the compliance contract.

    <none>

    address

    the address of the treasuryManager

    <none>

    ProxyBeacon

    the ProxyBeacon of the ModularCompliance

    <none>

    address

    the address of the ModularCompliance

    modularComplianceAddr_

    address

    the address of the ModularComplianceImpl

    <none>

    IBasicFrictionlessToken.FrictionlessTokenTypes

    the address of the ModularCompliance

    tokenType_

    IBasicFrictionlessToken.FrictionlessTokenTypes

    the type of token as defined by the IBasicFrictionlessToken.FrictionlessTokenTypes enumerated type

    <none>

    uint256

    the amount of supported compliances

    tokenType_

    IBasicFrictionlessToken.FrictionlessTokenTypes

    the type of token as defined by the IBasicFrictionlessToken.FrictionlessTokenTypes enumerated type

    <none>

    address[]

    the array of supported compliances

    tokenType_

    IBasicFrictionlessToken.FrictionlessTokenTypes

    the type of token as defined by the IBasicFrictionlessToken.FrictionlessTokenTypes enumerated type

    moduleToCheck_

    address

    the address of the modular compliance contract to verify

    <none>

    bool

    true if the compliance module supports the Frictionless token type, otherwise false

    modularComplianceAddr_

    address

    the address of the ModularCompliance contract

    <none>

    bool

    true if the address provided is a ModularCompliance contract, otherwise false

    string

    the URI of the off-chain claim for the user. i.e. The Frictionless Markets graphQL endpoint requires The msg.sender to be the Owner if the userType is the PROTOCOL_TREASURY requires The msg.sender to have the TREX Agent permissions (PROTOCOL_TREASURY or PROTOCOL_ADMIN) to add any user

    userAddress

    address

    the wallet address to verify

    <none>

    bool

    true if the address is permissioned in the Frictionless Protocol.

    userAddress

    address

    the address of the user's wallet to register

    userISOCountry

    uint16

    the ISO 3166-1 numeric code of the user, can be the place of residence or the location KYC/AML onboarding was undertaken. requires The msg.sender to have the TREX Agent permissions (PROTOCOL_TREASURY or PROTOCOL_ADMIN)

    <none>

    address

    address the address of the user's OnChainId (Identity) with the associated claims.

    userAddress

    address

    the address of the user's wallet to register requires The msg.sender to have the TREX Agent permissions (PROTOCOL_TREASURY or PROTOCOL_ADMIN)

    <none>

    address

    address the address of the user's OnChainId (Identity) with the associated claims.

    userIdentity

    address

    the address of the user's OnChainId (Identity)

    userType

    IFrictionlessPermissionsManager.FrictionlessPermissionedUser

    the type of the user as per the enum

    <none>

    bytes32

    signed claimData message to be used in the addUser unction once signed by the ClaimIssuer PK.

    userAddress

    address

    the address of the user's wallet to verify

    userType

    FrictionlessPermissionedUser

    the type of the user as per the enum

    <none>

    bool

    true if a valid permissioned user and has a valid claim, otherwise false.

    userIdentity

    address

    the address of the user's OnChainId (Identity)

    userType

    FrictionlessPermissionedUser

    the type of the user as per the enum

    claimSignature

    bytes

    the signed claimData by the ClaimIssuer

    <none>

    address

    address the address of the user's OnChainId (Identity) with the associated claims.

    userAddress

    address

    the address of the user's wallet requires The msg.sender to have the TREX Agent permissions (PROTOCOL_TREASURY or PROTOCOL_ADMIN) to remove any user

    <none>

    bool

    true if the user is removed from the Frictionless protocol along with its associated claim data, otherwise false.

    claimURI

    function setTreasuryManager(address newTreasuryManager_) external;
    function updateModularComplianceImpl(address newModularComplianceImpl_) external;
    function updateSupportedComplianceData(UpdateSupportedComplianceData[] calldata updateSupportedComplianceDataArr_)
        external;
    function updateModularComplianceData(UpdateModularComplianceData[] calldata updateModularComplianceDataArr_) external;
    function deployCompliance(IBasicFrictionlessToken.FrictionlessTokenTypes tokenType_) external returns (address);
    function treasuryManager() external view returns (address);
    function modularComplianceBeacon() external view returns (ProxyBeacon);
    function getModularComplianceImpl() external view returns (address);
    function getModularComplianceTokenType(address modularComplianceAddr_)
        external
        view
        returns (IBasicFrictionlessToken.FrictionlessTokenTypes);
    function getSupportedComplianceModulesCount(IBasicFrictionlessToken.FrictionlessTokenTypes tokenType_)
        external
        view
        returns (uint256);
    function getSupportedComplianceModules(IBasicFrictionlessToken.FrictionlessTokenTypes tokenType_)
        external
        view
        returns (address[] memory);
    function getSupportedComplianceInfo(IBasicFrictionlessToken.FrictionlessTokenTypes tokenType_)
        external
        view
        returns (ModularComplianceInfo memory);
    function isSupportedComplianceModule(IBasicFrictionlessToken.FrictionlessTokenTypes tokenType_, address moduleToCheck_)
        external
        view
        returns (bool);
    function isModularCompliance(address modularComplianceAddr_) external view returns (bool);
    event FrictionlessComplianceDeployed(
        IBasicFrictionlessToken.FrictionlessTokenTypes indexed tokenType, address newComplianceContract
    );
    error FrictionlessComplianceFactoryZeroAddr(string);
    error FrictionlessComplianceFactoryNotATreasuryManager(address);
    error FrictionlessComplianceFactoryNotAModularCompliance(address);
    error FrictionlessComplianceFactoryInvalidTokenType();
    error FrictionlessComplianceFactoryInvalidModularComplianceData(UpdateModularComplianceData modularComplianceData);
    struct SupportedComplianceData {
        uint256 maxModulesCount;
        EnumerableSet.AddressSet modules;
        bytes32[48] _gap;
    }
    struct ModularComplianceInfo {
        uint256 maxModulesCount;
        address[] modules;
    }
    struct UpdateModularComplianceData {
        address modularCompliance;
        ModularComplianceInfo complianceInfo;
        bool isAdding;
    }
    struct UpdateSupportedComplianceData {
        IBasicFrictionlessToken.FrictionlessTokenTypes tokenType;
        ModularComplianceInfo complianceInfo;
        bool isAdding;
    }
    function isPermissioned(address userAddress) external view returns (bool);
    function registerIdentity(address userAddress, uint16 userISOCountry) external returns (address);
    function getIdentity(address userAddress) external returns (address);
    function getClaimMsgHash(address userIdentity, IFrictionlessPermissionsManager.FrictionlessPermissionedUser userType)
        external
        view
        returns (bytes32);
    function hasClaim(address userAddress, FrictionlessPermissionedUser userType) external view returns (bool);
    function addUser(
        address userIdentity,
        FrictionlessPermissionedUser userType,
        bytes memory claimSignature,
        string memory claimURI
    ) external returns (address);
    function removeUser(address userAddress) external returns (bool);
    event FrictionlessPermissionedUserAdded(address userIdentity, uint256 userType, string claimURI);
    event FrictionlessPermissionedUserRegistered(address userAddress, uint16 userISOCountry);
    event FrictionlessPermissionedUserRemoved(address userAddress);
    error FrictionlessIsZeroAddress(string);
    error FrictionlessInvalidPermissionForTreasury();
    error FrictionlessUserIsNotPermssionedInvestor();
    struct Claim {
        address issuer;
        uint256 topic;
        uint8 scheme;
        address identity;
        bytes signature;
        bytes data;
    }
    enum FrictionlessPermissionedUser {
        PROTOCOL_TREASURY,
        PERMISSIONED_CUSTODIAN,
        PERMISSIONED_INVESTOR,
        PERMISSIONED_MANAGER,
        PERMISSIONED_CALCULATING_AGENT,
        PERMISSIONED_TRANSFER_AGENT,
        PERMISSIONED_FUND_ACCOUNTANT
    }

    IFrictionlessFXSwap

    Git Sourcearrow-up-right

    Inherits: IAbstractFeeModule

    Author: DEFYCA Labs S.à.r.l

    Copyright © 2023 DEFYCA Labs S.à.r.l Permission is hereby granted, free of charge, to any person obtaining a copy of the Frictionless protocol smart contracts (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL DEFYCA LABS S.à.r.l BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

    Interface defining the frictionless conversion and atomic swapping of any FrictionlessFundDepositToken currency pair on the Frictionless protocol. The FX rates are set from the live spot & forward FX partners on the protocol.

    hashtag
    Functions

    hashtag
    setFXDeskFeeAddr

    Sets the address of the FXDesk fee recipient Only Owner (PROTOCOL_ADMIN) can call this function

    Parameters

    Name
    Type
    Description

    hashtag
    setSwapFees

    Set the swap fees for the swaps of a token pair. The fees can be any combination of zero (0%) or upto 10000 bps (100%) on any directional transfer. Fees can only be set by the Owner (PROTOCOL_ADMIN).

    Parameters

    Name
    Type
    Description

    hashtag
    setTokenFee

    Set the fee associated with the swap of a Token and manages the mapping of the key to this set of Fees. Can only be set by the Owner (PROTOCOL_ADMIN).

    Parameters

    Name
    Type
    Description

    hashtag
    swapTokens

    Swaps tokens between addresses at a specified exchange rate Only PROTOCOL_TREASURY can call this function

    Parameters

    Name
    Type
    Description

    hashtag
    fxDeskFeeAddr

    Retrieves the address of the FXDesk fee recipient

    Returns

    Name
    Type
    Description

    hashtag
    treasuryManager

    Retrieves the Frictionless Treasury Manager contract

    Returns

    Name
    Type
    Description

    hashtag
    permissionManager

    Retrieves the Frictionless Permissions Manager contract

    Returns

    Name
    Type
    Description

    hashtag
    getSwapFeesInfo

    get the tokenFeeInfo set for the fees associated per token in an exchange.

    Parameters

    Name
    Type
    Description

    Returns

    Name
    Type
    Description

    hashtag
    getSwapFeeKeys

    Generates keys based on the packed encoding of the addresses of sets of tokens using the keccak256 hashing function. Used to store tokenFees in mappings.

    Parameters

    Name
    Type
    Description

    Returns

    Name
    Type
    Description

    hashtag
    getTokenFeeKey

    Generates a key based on the packed encoding of the addresses of both tokens using the keccak256 hashing function. Used to store tokenFees in mappings.

    Parameters

    Name
    Type
    Description

    Returns

    Name
    Type
    Description

    hashtag
    getSellingTokensAmount

    Calculates the amount of selling tokens based on the buying amount and exchange rate

    Parameters

    Name
    Type
    Description

    Returns

    Name
    Type
    Description

    hashtag
    Events

    hashtag
    FrictionlessFXTokensSwapped

    Event emitted upon successful token swaps

    hashtag
    Errors

    hashtag
    FrictionlessFXSwapInvalidTokenAddresses

    error thrown during setSwapFees if token adresses are invalid (zero addresses, equals addresses and etc.).

    hashtag
    FrictionlessFXSwapInvalidFeeRecipientAddr

    error thrown during setSwapFees, setTokenFee and swapTokens if the fxDeskFeeRecipient doesn't equal to the stored fxDeskFeeAddr

    hashtag
    FrictionlessFXSwapNotEnoughPermissions

    error thrown during swapTokens if the msg.sender is not a PROTOCOL_TREASURY.

    hashtag
    Structs

    hashtag
    FrictionlessTokenFXFeeInfo

    Structure representing token fee information including the token address and fee information

    AbstractFrictionlessComplianceModule

    Inherits: IFrictionlessComplianceModule, OwnableUpgradeable

    Author: DEFYCA Labs S.à.r.l

    Copyright © 2023 DEFYCA Labs S.à.r.l Permission is hereby granted, free of charge, to any person obtaining a copy of the Frictionless protocol smart contracts (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL DEFYCA LABS S.à.r.l BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

    address

    The address where the bought tokens will be sent

    buyingTokensAmount_

    uint256

    The amount of tokens being bought

    buyingTokenExchangeRate_

    uint256

    The exchange rate of the token being bought to the token being sold

    newFXDeskFeeAddr_

    address

    The new address of the FXDesk fee recipient

    token0FeeInfo_

    FrictionlessTokenFXFeeInfo

    The fees associated with the token0 (first token) in the token pair during the swap.

    token1FeeInfo_

    FrictionlessTokenFXFeeInfo

    The fees associated with the token1 (second token) in the token pair during the swap. throws FrictionlessFXSwapInvalidTokenAddresses if the token addresses are invalid. throws FrictionlessFXSwapInvalidFeeRecipientAddr if the feeRecipientAddr doesn't equal to the fxDeskFeeAddr. throws AbstractFeeModuleInvalidFeeRecipient if the feeRecipientAddr is a zero address throws AbstractFeeModuleInvalidFee if the feeInBps is not in the valid range (ZERO_FEES_IN_BPS to MAX_FEES_IN_BPS) emits FrictionlessFeeSet upon completion of the setting of the fee info for the token in either set of fees

    tokenFeeKey_

    bytes32

    The key, generated by the function getTokenFeeKey, which is used to map a specific swap polarity for tokens.

    tokenFeeInfo_

    FrictionlessTokenFXFeeInfo

    The fees associated with the swap of token, used in the calculation and disbursement of fees during swap of a token pair. throws FrictionlessFXSwapInvalidTokenAddresses if the token addresses are invalid. throws FrictionlessFXSwapInvalidFeeRecipientAddr if the feeRecipientAddr doesn't equal to the fxDeskFeeAddr. throws AbstractFeeModuleInvalidFeeRecipient if the feeRecipientAddr is a zero address throws AbstractFeeModuleInvalidFee if the feeInBps is not in the valid range (ZERO_FEES_IN_BPS to MAX_FEES_IN_BPS) emits FrictionlessTokenFeeSet upon completion of the setting of the fee info for the token

    sellingTokenAddr_

    address

    The address of the token to be sold

    buyingTokenAddr_

    address

    The address of the token to be bought

    tokenSender_

    address

    The address of the sender initiating the swap

    <none>

    address

    The address of the FXDesk fee recipient

    <none>

    IFrictionlessTreasuryManager

    The address of the Frictionless Treasury Manager contract

    <none>

    IFrictionlessPermissionsManager

    The address of the Frictionless Permissions Manager contract

    token0_

    address

    the address of the first token in an exchange

    token1_

    address

    the address of the second token in an exchange

    <none>

    FeeInfo

    FeeInfo set for the fees associated per token in an exchange.

    <none>

    FeeInfo

    token0_

    address

    the address of the token 0 in a transfer fee calculation

    token1_

    address

    the address of the token 1 in a transfer fee calculation

    <none>

    bytes32

    keys based on the packed encoding of the addresses of sets of tokens using the keccak256 hashing function.

    <none>

    bytes32

    token0_

    address

    the address of the token 0 in a transfer fee calculation

    token1_

    address

    the address of the token 1 in a transfer fee calculation

    <none>

    bytes32

    generates a key based on the packed encoding of the addresses of both tokens using the keccak256 hashing function.

    buyingTokensAmount_

    uint256

    The amount of tokens being bought

    buyingTokenExchangeRate_

    uint256

    The exchange rate of the token being bought to the token being sold

    <none>

    uint256

    The amount of selling tokens

    tokenRecipient_

    See {IFrictionlessComplianceModule}

    hashtag
    State Variables

    hashtag
    permissionsManager

    The IFrictionlessPermissionsManager for the protocol.

    hashtag
    complianceFactory

    The IFrictionlessComplianceFactory for the protocol.

    hashtag
    _complianceBound

    the mapping of compliance modules bound.

    hashtag
    Functions

    hashtag
    onlyApprovedCompliance

    modifier used to very that only approved compliance modules can be used.

    hashtag
    onlyBoundCompliance

    modifier used to very that only modules that are bound, can be used.

    hashtag
    __AbstractFrictionlessComplianceModule_init

    Initiatizes the compliance module

    Parameters

    Name
    Type
    Description

    frictionlessPermissionsManager_

    address

    the address of the frictionless permissions manager

    complianceFactory_

    address

    the address of the compliance dfactory

    hashtag
    setPermissionsManager

    Sets the instance of the IFrictionlessPermissionsManager to determine permissions for users.

    Parameters

    Name
    Type
    Description

    frictionlessPermissionsManager_

    address

    the address of the IFrictionlessPermissionsManager contract

    hashtag
    setComplianceFactory

    Sets the instance of the IFrictionlessComplianceFactory to determine the compliance module for the protocol.

    Parameters

    Name
    Type
    Description

    newComplianceFactory_

    address

    the address of the IFrictionlessComplianceFactory contract

    hashtag
    bindCompliance

    hashtag
    unbindCompliance

    hashtag
    moduleTransferAction

    hashtag
    moduleMintAction

    hashtag
    moduleBurnAction

    hashtag
    moduleCheck

    hashtag
    isComplianceBound

    hashtag
    isTreasury

    Verifies if the specified wallet address is a PROTOCOL_TREASURY user.

    Parameters

    Name
    Type
    Description

    userAddress_

    address

    Returns

    Name
    Type
    Description

    <none>

    bool

    true if the specified wallet address is a PROTOCOL_TREASURY user, otherwise false

    hashtag
    isCustodian

    Verifies if the specified wallet address is a PERMISSIONED_CUSTODIAN user.

    Parameters

    Name
    Type
    Description

    userAddress_

    address

    Returns

    Name
    Type
    Description

    <none>

    bool

    true if the specified wallet address is a PERMISSIONED_CUSTODIAN user, otherwise false

    hashtag
    isInvestor

    Verifies if the specified wallet address is a PERMISSIONED_INVESTOR user.

    Parameters

    Name
    Type
    Description

    userAddress_

    address

    Returns

    Name
    Type
    Description

    <none>

    bool

    true if the specified wallet address is a PERMISSIONED_INVESTOR user, otherwise false

    hashtag
    isManager

    Verifies if the specified wallet address is a PERMISSIONED_MANAGER user.

    Parameters

    Name
    Type
    Description

    userAddress_

    address

    Returns

    Name
    Type
    Description

    <none>

    bool

    true if the specified wallet address is a PERMISSIONED_MANAGER user, otherwise false

    hashtag
    isCalculatingAgent

    Verifies if the specified wallet address is a PERMISSIONED_CALCULATING_AGENT user.

    Parameters

    Name
    Type
    Description

    userAddress_

    address

    Returns

    Name
    Type
    Description

    <none>

    bool

    true if the specified wallet address is a PERMISSIONED_CALCULATING_AGENT user, otherwise false

    hashtag
    isTransferAgent

    Verifies if the specified wallet address is a PERMISSIONED_TRANSFER_AGENT user.

    Parameters

    Name
    Type
    Description

    userAddress_

    address

    Returns

    Name
    Type
    Description

    <none>

    bool

    true if the specified wallet address is a PERMISSIONED_TRANSFER_AGENT user, otherwise false

    hashtag
    isFundAccountant

    Verifies if the specified wallet address is a PERMISSIONED_FUND_ACCOUNTANT user.

    Parameters

    Name
    Type
    Description

    userAddress_

    address

    Returns

    Name
    Type
    Description

    <none>

    bool

    true if the specified wallet address is a PERMISSIONED_FUND_ACCOUNTANT user, otherwise false

    hashtag
    isUser

    Verifies if the specified wallet address is a permissioned user in the Frictionless protocol.

    Parameters

    Name
    Type
    Description

    userAddress_

    address

    Returns

    Name
    Type
    Description

    <none>

    bool

    true if the specified wallet address is a permissioned user in the Frictionless protocol, otherwise false

    hashtag
    hasClaim

    verify if the userAddress is permissioned in the Frictionless protocol and has a valid claim

    Parameters

    Name
    Type
    Description

    userAddress_

    address

    the address of the user's wallet to verify

    userType_

    IFrictionlessPermissionsManager.FrictionlessPermissionedUser

    the type of the user as per the enum

    Returns

    Name
    Type
    Description

    <none>

    bool

    true if a valid permissioned user and has a valid claim, otherwise false.

    hashtag
    _setPermissionsManager

    Impl of the setting of the permissions manager

    hashtag
    _setComplianceFactory

    Impl of the setting of the compliance factory

    hashtag
    _checkZeroAddr

    Verifies if an address is a zero address

    hashtag
    _onlyBoundCompliance

    Verifies if the compliance_ address supplied is bound as per the mapping

    hashtag
    _onlyValidCompliance

    Verifies if the compliance_ address supplied is valid

    hashtag
    _onlyApprovedCompliance

    Verifies if the msg.sender is a valid modular compliance

    hashtag
    _getTokenBound

    Returns the address of the IToken bound by this compliance

    hashtag
    _hasClaim

    Determine if a claim is present for a given userAddress and userType

    Parameters

    Name
    Type
    Description

    userAddress_

    address

    the address if the users wallet

    userType_

    IFrictionlessPermissionsManager.FrictionlessPermissionedUser

    the type of the user as defined by the enumeration IFrictionlessPermissionsManager.FrictionlessPermissionedUser

    Git Sourcearrow-up-right
    function setFXDeskFeeAddr(address newFXDeskFeeAddr_) external;
    function setSwapFees(
        FrictionlessTokenFXFeeInfo calldata token0FeeInfo_,
        FrictionlessTokenFXFeeInfo calldata token1FeeInfo_
    ) external;
    function setTokenFee(bytes32 tokenFeeKey_, FrictionlessTokenFXFeeInfo calldata tokenFeeInfo_) external;
    function swapTokens(
        address sellingTokenAddr_,
        address buyingTokenAddr_,
        address tokenSender_,
        address tokenRecipient_,
        uint256 buyingTokensAmount_,
        uint256 buyingTokenExchangeRate_
    ) external;
    function fxDeskFeeAddr() external view returns (address);
    function treasuryManager() external view returns (IFrictionlessTreasuryManager);
    function permissionManager() external view returns (IFrictionlessPermissionsManager);
    function getSwapFeesInfo(address token0_, address token1_) external view returns (FeeInfo memory, FeeInfo memory);
    function getSwapFeeKeys(address token0_, address token1_) external view returns (bytes32, bytes32);
    function getTokenFeeKey(address token0_, address token1_) external view returns (bytes32);
    function getSellingTokensAmount(uint256 buyingTokensAmount_, uint256 buyingTokenExchangeRate_)
        external
        view
        returns (uint256);
    event FrictionlessFXTokensSwapped(
        address sellingTokenAddr,
        address buyingTokenAddr,
        address tokenSender,
        address tokenRecipient,
        uint256 sellingTokensAmount,
        uint256 buyingTokensAmount,
        uint256 buyingTokenExchangeRate
    );
    error FrictionlessFXSwapInvalidTokenAddresses(address token0, address token1);
    error FrictionlessFXSwapInvalidFeeRecipientAddr(address newFeeRecipient);
    error FrictionlessFXSwapNotEnoughPermissions();
    struct FrictionlessTokenFXFeeInfo {
        address tokenAddr;
        uint256 feeAbsoluteLimit;
        FeeInfo feeInfo;
    }
    IFrictionlessPermissionsManager public override permissionsManager;
    IFrictionlessComplianceFactory public override complianceFactory;
    mapping(address => bool) private _complianceBound;
    modifier onlyApprovedCompliance();
    modifier onlyBoundCompliance();
    function __AbstractFrictionlessComplianceModule_init(
        address frictionlessPermissionsManager_,
        address complianceFactory_
    ) internal onlyInitializing;
    function setPermissionsManager(address frictionlessPermissionsManager_) external override onlyOwner;
    function setComplianceFactory(address newComplianceFactory_) external override onlyOwner;
    function bindCompliance(address compliance_) external override onlyApprovedCompliance;
    function unbindCompliance(address compliance_) external override;
    function moduleTransferAction(address from_, address to_, uint256 value_)
        external
        virtual
        override
        onlyBoundCompliance;
    function moduleMintAction(address to_, uint256 value_) external virtual override onlyBoundCompliance;
    function moduleBurnAction(address from_, uint256 value_) external virtual override onlyBoundCompliance;
    function moduleCheck(address, address, uint256, address) public view virtual override returns (bool);
    function isComplianceBound(address compliance_) public view override returns (bool);
    function isTreasury(address userAddress_) public view override returns (bool);
    function isCustodian(address userAddress_) public view override returns (bool);
    function isInvestor(address userAddress_) public view override returns (bool);
    function isManager(address userAddress_) public view override returns (bool);
    function isCalculatingAgent(address userAddress_) public view override returns (bool);
    function isTransferAgent(address userAddress_) public view override returns (bool);
    function isFundAccountant(address userAddress_) public view override returns (bool);
    function isUser(address userAddress_) public view override returns (bool);
    function hasClaim(address userAddress_, IFrictionlessPermissionsManager.FrictionlessPermissionedUser userType_)
        public
        view
        override
        returns (bool);
    function _setPermissionsManager(address newFrictionlessPermissionsManager_) internal;
    function _setComplianceFactory(address newComplianceFactory_) internal;
    function _checkZeroAddr(address addrToCheck_, string memory addrName_) internal pure;
    function _onlyBoundCompliance(address compliance_) internal view virtual;
    function _onlyValidCompliance(address compliance_) internal view;
    function _onlyApprovedCompliance() internal view;
    function _getTokenBound(address compliance_) internal view returns (address);
    function _hasClaim(address userAddress_, IFrictionlessPermissionsManager.FrictionlessPermissionedUser userType_)
        internal
        view
        virtual
        returns (bool);

    IFrictionlessTreasuryManager

    Author: DEFYCA Labs S.à.r.l

    Copyright © 2023 DEFYCA Labs S.à.r.l Permission is hereby granted, free of charge, to any person obtaining a copy of the Frictionless protocol smart contracts (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL DEFYCA LABS S.à.r.l BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

    The IFrictionlessTreasuryManager is responsible for all token operations, minting, transferring and burning in the Frictionless protocol. The tokens and their lifecycles are defined in the public README for the Frictionless protocol at https://gitlab.com/dfyclabs/protocol/dfyclabs-tokens/-/tree/main?ref_type=heads#tokens-overview

    hashtag
    Functions

    hashtag
    setTokensInitData

    Sets and associates the implementation authority with the associated token type

    Parameters

    Name
    Type
    Description

    initDataArr_

    FrictionlessTokenInitData[]

    the FrictionlessTokenInitData configuration associating the implementation authority with the associated token type.

    hashtag
    mintFundDepositForTreasury

    Mints a Fund Deposit Token in the specified currency/IBAN pair. This function is invoked to create the genesis mint of the deposit token in the PROTOCOL_TREASURY.

    Parameters

    Name
    Type
    Description

    depositData

    IFrictionlessFundDepositToken.FFDImmutableData

    the immutable deposit data for the token

    treasuryAddress

    address

    the address of the treasury, which receives the deposit tokens

    amount

    uint256

    the amount of tokens

    Returns

    Name
    Type
    Description

    <none>

    address

    address of the token minted emits FrictionlessTokenMinted event throws error FrictionlessTreasuryManagerInvalidDepositData if the deposit data is invalid. requires the depositData.currency to be a 3 letter currency code requires the depositData.description to be not empty requires the depositData.IBAN to be not empty

    hashtag
    mintDigitalSecurity

    Mints a FrictionlessDigitalSecurityToken as the future dated cash distribution from the underlying FrictionlessOnChainAssetToken. This function is invoked to create the genesis mint of the deposit token in the PROTOCOL_TREASURY.

    Parameters

    Name
    Type
    Description

    initData

    IFrictionlessDigitalSecurityToken.FDSImmutableData

    the immutable data for the token

    updateData

    IFrictionlessDigitalSecurityToken.FDSMutableData

    the mutable data for the token

    amount

    uint256

    the amount of tokens

    Returns

    Name
    Type
    Description

    <none>

    address

    address of the token minted emits FrictionlessTokenMinted event throws error FrictionlessTreasuryManagerInvalidFDSImmutableData if the initData is invalid. requires the initData.currency to be a 3 letter currency code requires the initData.onChainAssetAddress to be non 0 address

    hashtag
    mintOnChainAsset

    Mints a FrictionlessOnChainAssetToken as the representation of the asset to be securitized, fractionalized & sold. This function is invoked to create the genesis mint of the deposit token to the PERMISSIONED_CUSTODIAN.

    Parameters

    Name
    Type
    Description

    specData

    IFrictionlessOnChainAssetToken.FOCASpecData

    the immutable data for the token

    issuanceData

    IFrictionlessOnChainAssetToken.FOCAIssuanceData

    the issuance data for the token

    updateData

    IFrictionlessOnChainAssetToken.FOCAUpdateData

    the update data for the token

    Returns

    Name
    Type
    Description

    <none>

    address

    address of the token minted emits FrictionlessTokenMinted event throws error FrictionlessTreasuryManagerInvalidFOCASpecData or FrictionlessTreasuryManagerInvalidFOCAIssuanceData if the specData or issuanceData is invalid.

    hashtag
    mintTokenForUser

    Used to increase the mint of a Frictionless token which already exists.

    Parameters

    Name
    Type
    Description

    token

    address

    the address of the token

    userAddress

    address

    the address to min the token to

    amount

    uint256

    the amount of tokens to mint emits FrictionlessTokenMinted event

    hashtag
    transferToken

    Used to increase the mint of a Frictionless token which already exists.

    Parameters

    Name
    Type
    Description

    token

    address

    the address of the token

    userAddressFrom

    address

    the address to transfer the tokens from

    userAddressTo

    address

    the address to transfer the tokens to

    hashtag
    burnToken

    Used to burn an amount of Frictionless token which already exists.

    Parameters

    Name
    Type
    Description

    token

    address

    the address of the token

    userAddress

    address

    the address to burn the tokens from

    amount

    uint256

    the amount of tokens to burn emits FrictionlessTokenBurned event

    hashtag
    getFundDepositToken

    returns the address of the fund deposit token by currency and fundIBAN

    Parameters

    Name
    Type
    Description

    currency_

    string

    the currency of the fund deposit token

    fundIBAN_

    string

    the fundIBAN of the fund deposit token

    Returns

    Name
    Type
    Description

    <none>

    address

    the address of the fund deposit token for specified currency and fundIBAN

    hashtag
    getFundDepositTokenKey

    returns fund deposit token key by currency and fundIBAN

    Parameters

    Name
    Type
    Description

    currency_

    string

    the currency of the fund deposit token you need

    fundIBAN_

    string

    the fundIBAN of the fund deposit token you need

    Returns

    Name
    Type
    Description

    <none>

    bytes32

    the fund deposit token key

    hashtag
    Events

    hashtag
    FrictionlessTokenMinted

    Event emitted when a FrictionlessFundDeposit, FrictionlessDigitalSecurity or FrictionlessOnChainAsset is minted.

    hashtag
    FrictionlessTokenTransferred

    Event emitted when a FrictionlessFundDeposit, FrictionlessDigitalSecurity or FrictionlessOnChainAsset is transferred.

    hashtag
    FrictionlessTokenBurned

    Event emitted when a FrictionlessFundDeposit, FrictionlessDigitalSecurity or FrictionlessOnChainAsset is burned.

    hashtag
    Errors

    hashtag
    FrictionlessIsZeroAddress

    throws if specific address is zero.

    hashtag
    FrictionlessTreasuryManagerNotAProtocolTreasury

    error throw if the function caller is not a PROTOCOL_TREASURY address. Thrown during the mintFundDepositForTreasury

    hashtag
    FrictionlessTreasuryManagerFundDepositTokenAlreadyExists

    error throw if the FundDepositToken for specified currency and fundIBAN already exists

    hashtag
    FrictionlessTreasuryManagerInvalidTokenInitData

    error throw if the data for the token init data FrictionlessTokenInitData is invalid. Thrown during the _setTokensInitData

    hashtag
    FrictionlessTreasuryManagerUnableToUpdateTokenInitData

    error throw if the data for the token init data FrictionlessTokenInitData is already set. Thrown during the _setTokensInitData

    hashtag
    FrictionlessTreasuryManagerInvalidDepositData

    error throw if the data for the IFrictionlessFundDepositToken is invalid. Thrown during the mintFundDepositForTreasury

    hashtag
    FrictionlessTreasuryManagerInvalidFDSImmutableData

    error throw if the data for the IFrictionlessDigitalSecurityToken is invalid. Thrown during the mintDigitalSecurity

    hashtag
    FrictionlessTreasuryManagerInvalidFOCASpecData

    error throw if the data for the IFrictionlessDigitalSecurityToken is invalid. Thrown during the mintOnChainAsset

    hashtag
    FrictionlessTreasuryManagerInvalidFOCAIssuanceData

    error throw if the data for the IFrictionlessDigitalSecurityToken is invalid. Thrown during the mintOnChainAsset

    hashtag
    Structs

    hashtag
    FrictionlessTokenInitData

    Structure that encapsulates both the implAuthority and the compliance for the specific token.

    Git Sourcearrow-up-right

    Manager Contracts

    The Manager Contracts are the main entry points to the Frictionless protocol, they perform market functions such as permission management, treasury operations, issuance, transfer and settlement of securities, and attestations of deposits (proof-of-reserve) for the underlying of FrictionlessFundDepositTokens.

    There are four main manager contracts in the Frictionless protocol, as described below.

    • FrictionlessPermissionsManager

    hashtag

    The FrictionlessPermissionsManager defines a set of functions and events related to managing participants' permissions in the Frictionless protocol.

    The interface includes an enumeration FrictionlessPermissionedUser that enumerates different participants in the Frictionless protocol, such as PROTOCOL_TREASURY, PERMISSIONED_CUSTODIAN, etc.

    Only valid agents can register, add or remove users and their associated claims.

    hashtag

    The FrictionlessTransferManager manages the transfer of tokens within the Frictionless protocol. It is also responsible for the collection of fees associated with the exchange of tokens. These fees are mapped to specific fee schedules set by managers on their respective issuances.

    The FrictionlessTransferManager overview is provided in the source .

    circle-info

    The Frictionless protocol enables GPs and Managers to collect fees on the primary issuance and secondary trades of digital securities.

    circle-check

    The Frictionless protocol enables Investors to bilaterally trade digital securities via the FrictionlessTransferManager smart contract whilst enabling Managers to optionally collect fees on the transaction.

    See mode

    circle-check

    The Frictionless protocol enables Managers and GPs to control cash distributions, waterfalls, and capital calls without the direct action of Investors, enabling sophisticated automation via the Frictionless Markets APIs and Manager automation interface.

    See mode

    hashtag
    onlyTreasury Mode

    exchangeTokens , this function will execute the exchange of tokens between two counterparties, but it is executed by the PROTOCOL_TREASURY as the transfer agent optionally collecting fees. For example, payment in FrictionlessFundDepositToken by an Investor for FricitonlessDigitalSecurityToken held by a custodian (Primary trade) or FricitonlessDigitalSecurityToken held by another Investor (secondary trade).

    The exchange flow is as follows:

    1. The PROTOCOL_ADMIN optionally sets the transfer fees for the token inbound and outbound.

    2. The PROTOCOL_TREASURY invokes the exchangeTokens function, indicating the polarity of the transaction, such as cash for cash, cash for security, security for cash, or security for security. There are many options, but they all result in the same outcome, the compliant transfer of a Frictionless token for another Frictionless token in a single atomic transaction on-chain.

    More scenarios for DvP are described in the source .

    hashtag
    onlyCounterpart Mode

    createTransferOffer confirmTransferOffer, cancelTransferOffer these functions will execute the exchange tokens in a bilateral P2P mode between two counterparties in a maker-taker mode. This mode also optionally enables the protocol to collect fees.

    The exchange flow is as follows:

    1. The PROTOCOL_ADMIN optionally sets the transfer fees for the token inbound and outbound.

    2. Investor X invokes the createTransferOffer function, indicating the offer, such as cash for cash, cash for security, security for cash, or security for security. There are many options, but they all result in the same outcome, the compliant transfer of a Frictionless token for another Frictionless token in a single atomic transaction on-chain.

    3. Investor Y can accept the offer by invoking the

    hashtag

    The FrictionlessTreasuryManager manages the minting, transfer, and burning of various within the Frictionless protocol

    1. Token Minting and Management:

      • The contract provides functions to mint different types of tokens within the Frictionless protocol, including Fund Deposit Tokens (mintFundDepositForTreasury), Digital Security Tokens (mintDigitalSecurity), and On-Chain Asset Tokens (mintOnChainAsset).

    The PROTOCOL_ADMIN is the only role permissioned to initially mint any Frictionless tokens, thereafter valid agents such as the PROTOCOL_TREASURY are permitted to increase supply (mint to address), transfer and burn Frictionless tokens.

    hashtag

    The FrictionlessAttestationManager responsible for providing attestations of the balances held in the underlying funding account for each FrictionlessFundDepositToken. The attestation is provided and signed by an independent 3rd party, known as PERMISSIONED_FUND_ACCOUNTANT in the Frictionless protocol.

    circle-check

    Attestations are proof of balances in each currency on a regular basis for example, daily or hourly, the attestation data is based on the following snapshot of the currency account underpinning the FrictionlessFundDepositToken.

    ATTESTATION FIELD
    ATTESTATION COMMENT

    The attestation workflows are described in the source .

    function setTokensInitData(FrictionlessTokenInitData[] calldata initDataArr_) external;
    function mintFundDepositForTreasury(
        IFrictionlessFundDepositToken.FFDImmutableData calldata depositData,
        address treasuryAddress,
        uint256 amount
    ) external returns (address);
    function mintDigitalSecurity(
        IFrictionlessDigitalSecurityToken.FDSImmutableData memory initData,
        IFrictionlessDigitalSecurityToken.FDSMutableData memory updateData,
        uint256 amount,
        address userAddress
    ) external returns (address);
    function mintOnChainAsset(
        IFrictionlessOnChainAssetToken.FOCASpecData memory specData,
        IFrictionlessOnChainAssetToken.FOCAIssuanceData memory issuanceData,
        IFrictionlessOnChainAssetToken.FOCAUpdateData memory updateData,
        address custodianAddress
    ) external returns (address);
    function mintTokenForUser(address token, address userAddress, uint256 amount) external;
    function transferToken(address token, address userAddressFrom, address userAddressTo, uint256 amount) external;
    function burnToken(address token, address userAddress, uint256 amount) external;
    function getFundDepositToken(string calldata currency_, string calldata fundIBAN_) external view returns (address);
    function getFundDepositTokenKey(string memory currency_, string memory fundIBAN_) external pure returns (bytes32);
    event FrictionlessTokenMinted(
        IBasicFrictionlessToken.FrictionlessTokenTypes tokenType,
        address token,
        string tokenName,
        string tokenSymbol,
        uint256 amount,
        address toAddress
    );
    event FrictionlessTokenTransferred(
        IBasicFrictionlessToken.FrictionlessTokenTypes tokenType,
        address token,
        uint256 amount,
        address fromAddress,
        address toAddress
    );
    event FrictionlessTokenBurned(
        IBasicFrictionlessToken.FrictionlessTokenTypes tokenType, address token, uint256 amount, address fromAddress
    );
    error FrictionlessIsZeroAddress(string);
    error FrictionlessTreasuryManagerNotAProtocolTreasury(address);
    error FrictionlessTreasuryManagerFundDepositTokenAlreadyExists(string currency, string fundIBAN);
    error FrictionlessTreasuryManagerInvalidTokenInitData(FrictionlessTokenInitData);
    error FrictionlessTreasuryManagerUnableToUpdateTokenInitData(IBasicFrictionlessToken.FrictionlessTokenTypes);
    error FrictionlessTreasuryManagerInvalidDepositData(IFrictionlessFundDepositToken.FFDImmutableData);
    error FrictionlessTreasuryManagerInvalidFDSImmutableData(IFrictionlessDigitalSecurityToken.FDSImmutableData);
    error FrictionlessTreasuryManagerInvalidFOCASpecData(IFrictionlessOnChainAssetToken.FOCASpecData);
    error FrictionlessTreasuryManagerInvalidFOCAIssuanceData(IFrictionlessOnChainAssetToken.FOCAIssuanceData);
    struct FrictionlessTokenInitData {
        address implAuthority;
        IBasicFrictionlessToken.FrictionlessTokenTypes tokenType;
    }

    userAddress

    address

    the address of the protocol user, which receives the digital security tokens

    custodianAddress

    address

    the address of the protocol custodian, which receives the FrictionlessOnChainAssetToken

    amount

    uint256

    the amount of tokens to mint emits FrictionlessTokenTransferred event

    The transfer is enacted using the ERC-3643-compliant token transfer
    IToken.forcedTransfer
    .
    confirmTransferOffer
    function, ensuring the ERC-3643-compliant token transfer using
    IToken.transferFrom
    .

    Tokens are associated with compliance contracts, and their minting is subject to specific conditions, roles, and permissions.

  • Token Transfer and Burning:

    • The contract allows for the transfer and burning of tokens through functions like transferToken and burnToken. These actions are performed by an agent with the necessary permissions.

  • Fund Deposit Token Management:

    • The contract keeps track of existing Fund Deposit Tokens using a mapping _existingFundDepositTokens. It prevents the creation of duplicate Fund Deposit Tokens for the same currency and fund IBAN.

  • LAST_TX_COUNTERPARTY_ID

    The ID of the counterparty in the last transaction on the account

    LAST_TX_TIMESTAMP

    The timestamp (same format as REPORT_END_DATE) in the last transaction on the account

    LAST_TX_AMOUNT

    The amount of the the last transaction on the account, A credit transaction is positive and a debit transaction is negative

    CASH_IBAN

    The IBAN of the cash account

    CURRENCY

    The 3-letter currency code of the cash account

    REPORT_START_DATE

    The start of this report, for example, yesterday at 6AM

    REPORT_END_DATE

    The end of this report, for example, today at 6AM

    CASH_BALANCE

    The actual balance on the account as of REPORT_END_DATEfor example, today 6AM

    FrictionlessTransferManager
    FrictionlessTreasuryManager
    FrictionlessAttestationManager
    FrictionlessPermissionsManager
    FrictionlessTransferManager
    READMEarrow-up-right
    onlyCounterpart
    onlyTreasury
    READMEarrow-up-right
    FrictionlessTreasuryManager
    tokens
    FrictionlessAttestationManager
    READMEarrow-up-right
    Schematic of Frictionless transfer of tokens by the PROTOCOL_TREASURY
    Schematic of Frictionless transfer of tokens bilaterally by Investors

    IFrictionlessERC20ConverterManager

    Git Sourcearrow-up-right

    Inherits: IAbstractFeeModule

    Author: DEFYCA Labs S.à.r.l

    Copyright © 2023 DEFYCA Labs S.à.r.l Permission is hereby granted, free of charge, to any person obtaining a copy of the Frictionless protocol smart contracts (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL DEFYCA LABS S.à.r.l BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

    Interface defining the frictionless conversion and atomic swapping of ERC-20 tokens for FrictionlessFundDepositToken on the Frictionless protocol. The conversion of tokens is considered frictionless as the protocol does not impose any fee structures on the conversion itself.

    hashtag
    Functions

    hashtag
    pause

    See {PausableUpgradeable-_pause}

    hashtag
    unpause

    See {PausableUpgradeable-_unpause}

    hashtag
    setConvertTokensFees

    Set the conversion fees for the token pair. The fees can be any combination of zero (0%) or upto 10000 bps (100%) on any directional transfer. Fees can only be set by the Owner (PROTOCOL_ADMIN).

    Parameters

    Name
    Type
    Description

    hashtag
    setConvertTokensFee

    Set the conversion fees for the token pair using the tokenFeeKey_. The fees can be any combination of zero (0%) or upto 10000 bps (100%) on any directional transfer. Fees can only be set by the Owner (PROTOCOL_ADMIN).

    Parameters

    Name
    Type
    Description

    hashtag
    removeFrictionlessTokensConvertInfo

    Removes the conversion fees for the token pair using the tokenFeeKey_. Fees can only be set by the Owner (PROTOCOL_ADMIN).

    Parameters

    Name
    Type
    Description

    hashtag
    addFrictionlessTokensConvertInfo

    Sets the mapping for the convertible tokens in the contract, calling this will add a new conversion pair to the contract.

    Parameters

    Name
    Type
    Description

    hashtag
    convertFromERC20

    Converts from an ERC20 token to a FrictionlessFundDepositToken, using the safe precision conversion. The ERC20 token is transferred to configured treasuryAddress in the conversion and the minted FrictionlessFundDepositToken is sent to the msg.sender

    Parameters

    Name
    Type
    Description

    hashtag
    convertFromERC20

    Converts from an ERC20 token to a FrictionlessFundDepositToken, using the safe precision conversion. The ERC20 token is transferred to configured treasuryAddress in the conversion and the minted FrictionlessFundDepositToken is sent to the convertedTokensRecipient_

    Parameters

    Name
    Type
    Description

    Returns

    Name
    Type
    Description

    hashtag
    convertToERC20

    Converts to an ERC20 token from a FrictionlessFundDepositToken, using the safe precision conversion. The FrictionlessFundDepositToken is burned in the conversion and the ERC20 is sent to the msg.sender from the treasuryAddress.

    Parameters

    Name
    Type
    Description

    Returns

    Name
    Type
    Description

    hashtag
    convertToERC20

    Converts to an ERC20 token from a FrictionlessFundDepositToken, using the safe precision conversion. The FrictionlessFundDepositToken is burned in the conversion and the ERC20 is sent to the convertedTokensRecipient_ from the treasuryAddress.

    Parameters

    Name
    Type
    Description

    Returns

    Name
    Type
    Description

    hashtag
    getConvertTokenInfo

    Returns the FrictionlessTokensConvertInfo for the given conversion key

    Parameters

    Name
    Type
    Description

    Returns

    Name
    Type
    Description

    hashtag
    getConvertTokenKeysByToken

    Returns the conversion keys for the given tokenAddr_

    Parameters

    Name
    Type
    Description

    Returns

    Name
    Type
    Description

    hashtag
    getConvertTokenKeysCountByToken

    Returns the count of conversion keys for the given tokenAddr_

    Parameters

    Name
    Type
    Description

    Returns

    Name
    Type
    Description

    hashtag
    getConvertTokenInfosByToken

    Returns the FrictionlessTokensConvertInfo for the given tokenAddr_

    Parameters

    Name
    Type
    Description

    Returns

    Name
    Type
    Description

    hashtag
    isTokenSupported

    Returns true if the token specified by the tokenAddr_ has been registered as a valid convertible pair.

    Parameters

    Name
    Type
    Description

    Returns

    Name
    Type
    Description

    hashtag
    isTokenPairSupported

    Returns true if the token pair specified have been registered as a valid convertible pair.

    Parameters

    Name
    Type
    Description

    Returns

    Name
    Type
    Description

    hashtag
    isConvertTokenKeySupported

    Returns true if the conversion key is supported.

    Parameters

    Name
    Type
    Description

    Returns

    Name
    Type
    Description

    hashtag
    getConvertTokensKey

    Returns the conversion key for the given token pair.

    Parameters

    Name
    Type
    Description

    Returns

    Name
    Type
    Description

    hashtag
    Events

    hashtag
    FrictionlessTokensConverted

    Event emitted when a successful conversion occurs between an ERC20 and a FrictionlessFuncDepositToken.

    hashtag
    Errors

    hashtag
    FrictionlessERC20ConverterManagerInvalidTokenConvertInfo

    thrown during addFrictionlessTokensConvertInfo if the tokensConvertInfoArr_ contains zero addresses

    hashtag
    FrictionlessERC20ConverterManagerUnableToUpdateConvertInfo

    thrown during addFrictionlessTokensConvertInfo if the tokensConvertInfoArr_ cannot be updated

    hashtag
    FrictionlessERC20ConverterManagerUnsupportedPair

    hashtag
    FrictionlessERC20ConverterManagerInvalidTokensAmountAfterConversion

    thrown during a convert to/from an ERC20 if the conversion resolves to zero

    hashtag
    FrictionlessERC20ConverterManagerIdenticalAddresses

    thrown during a convert to/from an ERC20 if the conversion is attempted for the same token

    hashtag
    FrictionlessERC20ConverterManagerZeroAddress

    thrown if the IFrictionlessERC20ConverterManager is configured as a zero address

    hashtag
    Structs

    hashtag
    FrictionlessTokensConvertInfo

    Struct to represent the conversion between an ERC20 token and a FrictionlessFundDepositToken on the Frictionless protocol

    uint256

    the amount of tokens to convert

    uint256

    the amount of tokens to convert

    erc20Token_

    address

    the address of the ERC20 token.

    fundDepositToken_

    address

    the address of the FundDeposit token.

    feeInfo_

    FeeInfo

    The fees associated with the conversion of the token pair. throws FrictionlessERC20ConverterManagerUnsupportedPair if the token pair is not valid throws AbstractFeeModuleInvalidFeeRecipient if the feeRecipientAddr is a zero address throws AbstractFeeModuleInvalidFee if the feeInBps is not in the valid range (ZERO_FEES_IN_BPS to MAX_FEES_IN_BPS) emits FrictionlessTokenFeeSet upon completion of the setting of the fee info for the token in either set of fees

    tokenFeeKey_

    bytes32

    the tokenFeeKey as determined getConvertTokensKey

    feeInfo_

    FeeInfo

    The fees associated with the conversion of the token pair. throws FrictionlessERC20ConverterManagerUnsupportedPair if the token pair is not valid throws AbstractFeeModuleInvalidFeeRecipient if the feeRecipientAddr is a zero address throws AbstractFeeModuleInvalidFee if the feeInBps is not in the valid range (ZERO_FEES_IN_BPS to MAX_FEES_IN_BPS) emits FrictionlessTokenFeeSet upon completion of the setting of the fee info for the token in either set of fees

    erc20Token_

    address

    the address of the ERC20 token.

    fundDepositToken_

    address

    the address of the FundDeposit token.

    tokensConvertInfoArr_

    FrictionlessTokensConvertInfo[]

    the array of token conversions to set. throws FrictionlessERC20ConverterManagerInvalidTokenConvertInfo if the tokensConvertInfoArr_ contains zero addresses throws FrictionlessERC20ConverterManagerUnableToUpdateConvertInfo if the tokensConvertInfoArr_ cannot be updated

    erc20Token_

    address

    the address of the ERC20 token to convert from, which must exist in a FrictionlessTokensConvertInfo in order to succeed.

    fundDepositToken_

    address

    the address of the FundDeposit token to convert to, which must exist in a FrictionlessTokensConvertInfo in order to succeed.

    erc20TokensAmount_

    uint256

    the amount of tokens to convert throws FrictionlessERC20ConverterManagerInvalidTokenType if the tokenAddr_ is not a configured convertible erc20Token throw FrictionlessERC20ConverterManagerInvalidTokensAmountAfterConversion if the conversion resolves to zero Emits the event FrictionlessTokensConverted detailing the full convertibility

    erc20Token_

    address

    the address of the ERC20 token to convert from, which must exist in a FrictionlessTokensConvertInfo in order to succeed.

    fundDepositToken_

    address

    the address of the FundDeposit token to convert to, which must exist in a FrictionlessTokensConvertInfo in order to succeed.

    convertedTokensRecipient_

    address

    the destination of the converted FrictionlessFundDepositToken

    <none>

    uint256

    the amount of FrictionlessFundDepositToken converted throws FrictionlessERC20ConverterManagerInvalidTokenType if the tokenAddr_ is not a configured convertible erc20Token throw FrictionlessERC20ConverterManagerInvalidTokensAmountAfterConversion if the conversion resolves to zero Emits the event FrictionlessTokensConverted detailing the full convertibility

    erc20Token_

    address

    fundDepositToken_

    address

    the address of the FrictionlessFundDepositToken token to convert from, which must exist in a FrictionlessTokensConvertInfo in order to succeed.

    fundDepositTokensAmount_

    uint256

    the amount of tokens to convert

    <none>

    uint256

    the amount of ERC20 converted throws FrictionlessERC20ConverterManagerInvalidTokenType if the tokenAddr_ is not a configured convertible fundDepositToken throw FrictionlessERC20ConverterManagerInvalidTokensAmountAfterConversion if the conversion resolves to zero Emits the event FrictionlessTokensConverted detailing the full convertibility

    erc20Token_

    address

    fundDepositToken_

    address

    the address of the FrictionlessFundDepositToken token to convert from, which must exist in a FrictionlessTokensConvertInfo in order to succeed.

    convertedTokensRecipient_

    address

    the destination of the converted ERC20 token

    <none>

    uint256

    the amount of ERC20 converted throws FrictionlessERC20ConverterManagerInvalidTokenType if the tokenAddr_ is not a configured convertible fundDepositToken throw FrictionlessERC20ConverterManagerInvalidTokensAmountAfterConversion if the conversion resolves to zero Emits the event FrictionlessTokensConverted detailing the full convertibility

    convertInfoKey_

    bytes32

    the address of the token to validate.

    <none>

    FrictionlessTokensConvertInfo

    the FrictionlessTokensConvertInfo for the given conversion key

    tokenAddr_

    address

    the address of the token to validate.

    <none>

    bytes32[]

    the conversion keys arr for the given tokenAddr_

    tokenAddr_

    address

    the address of the token to validate.

    <none>

    uint256

    the count of conversion keys arr for the given tokenAddr_

    tokenAddr_

    address

    the address of the token to validate.

    <none>

    FrictionlessTokensConvertInfo[]

    the FrictionlessTokensConvertInfo for the given tokenAddr_

    tokenAddr_

    address

    the address of the token to validate.

    <none>

    bool

    true if the token specified by the tokenAddr_ has been registered as a valid convertible pair, otherwise false

    erc20Token_

    address

    the address of the ERC20 token.

    fundDepositToken_

    address

    the address of the FundDeposit token.

    <none>

    bool

    true if the token pair specified have been registered as a valid convertible pair, otherwise false

    convertTokenKey_

    bytes32

    the conversion key as defined by getConvertTokensKey

    <none>

    bool

    true if Returns true if the conversion key is supported, otherwise false

    token0_

    address

    the first token in the convertible pair

    token1_

    address

    the second token in the convertible pair

    <none>

    bytes32

    the conversion key for the given token pair throws FrictionlessERC20ConverterManagerIdenticalAddresses if both tokens are identical throws FrictionlessERC20ConverterManagerZeroAddress if the tokens are a zero address

    erc20TokensAmount_

    fundDepositTokensAmount_

    function pause() external;
    function unpause() external;
    function setConvertTokensFees(address erc20Token_, address fundDepositToken_, FeeInfo calldata feeInfo_) external;
    function setConvertTokensFee(bytes32 tokenFeeKey_, FeeInfo calldata feeInfo_) external;
    function removeFrictionlessTokensConvertInfo(address erc20Token_, address fundDepositToken_) external;
    function addFrictionlessTokensConvertInfo(FrictionlessTokensConvertInfo[] calldata tokensConvertInfoArr_) external;
    function convertFromERC20(address erc20Token_, address fundDepositToken_, uint256 erc20TokensAmount_)
        external
        returns (uint256);
    function convertFromERC20(
        address erc20Token_,
        address fundDepositToken_,
        address convertedTokensRecipient_,
        uint256 erc20TokensAmount_
    ) external returns (uint256);
    function convertToERC20(address erc20Token_, address fundDepositToken_, uint256 fundDepositTokensAmount_)
        external
        returns (uint256);
    function convertToERC20(
        address erc20Token_,
        address fundDepositToken_,
        address convertedTokensRecipient_,
        uint256 fundDepositTokensAmount_
    ) external returns (uint256);
    function getConvertTokenInfo(bytes32 convertInfoKey_) external view returns (FrictionlessTokensConvertInfo memory);
    function getConvertTokenKeysByToken(address tokenAddr_) external view returns (bytes32[] memory);
    function getConvertTokenKeysCountByToken(address tokenAddr_) external view returns (uint256);
    function getConvertTokenInfosByToken(address tokenAddr_)
        external
        view
        returns (FrictionlessTokensConvertInfo[] memory);
    function isTokenSupported(address tokenAddr_) external view returns (bool);
    function isTokenPairSupported(address erc20Token_, address fundDepositToken_) external view returns (bool);
    function isConvertTokenKeySupported(bytes32 convertTokenKey_) external view returns (bool);
    function getConvertTokensKey(address token0_, address token1_) external pure returns (bytes32);
    event FrictionlessTokensConverted(
        address fromToken, address toToken, address toTokensRecipient, uint256 fromAmount, uint256 toAmount
    );
    error FrictionlessERC20ConverterManagerInvalidTokenConvertInfo(FrictionlessTokensConvertInfo);
    error FrictionlessERC20ConverterManagerUnableToUpdateConvertInfo(FrictionlessTokensConvertInfo);
    error FrictionlessERC20ConverterManagerUnsupportedPair(address, address);
    error FrictionlessERC20ConverterManagerInvalidTokensAmountAfterConversion();
    error FrictionlessERC20ConverterManagerIdenticalAddresses();
    error FrictionlessERC20ConverterManagerZeroAddress();
    struct FrictionlessTokensConvertInfo {
        address erc20Token;
        address fundDepositToken;
        address treasuryAddress;
    }

    IFrictionlessTransferManager

    Inherits: IAbstractFeeModule

    Author: DEFYCA Labs S.à.r.l

    Copyright © 2023 DEFYCA Labs S.à.r.l Permission is hereby granted, free of charge, to any person obtaining a copy of the Frictionless protocol smart contracts (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL DEFYCA LABS S.à.r.l BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

    The IFrictionlessTransferManager is responsible for the management of the various transfer methodologies, fees processing, and defined control paradigm for DvP for all tokens in the Frictionless protocol. The tokens and their lifecycles are defined in the public README for the Frictionless protocol at https://gitlab.com/dfyclabs/protocol/dfyclabs-tokens/-/blob/main/README.md?ref_type=heads#funds-flows

    hashtag
    Functions

    hashtag
    updateMinRedeemAmount

    Set a minimum redemption amount, to ensure there is meaningful settlement amounts, generally this is used to ensure FIAT transfers are above a minimum banking threshold, such as 1 USD.

    Parameters

    Name
    Type
    Description

    newMinRedeemAmount_

    uint256

    the minimum redemption amount, if not reached , typically throws FrictionlessTransferManagerRedeemAmountIsLessThanMinimum

    hashtag
    setTransferFees

    Set the transfer fees for the exchange/settlement of a token pair. The fees can be any combination of zero (0%) or upto 10000 bps (100%) on any directional transfer. Fees can only be set by the Owner (PROTOCOL_ADMIN).

    Parameters

    Name
    Type
    Description

    token0FeeInfo_

    TokenFeeInfo

    The fees associated with the transfer of token0 (first token) in the exchange/settlement of the token pair.

    token1FeeInfo_

    TokenFeeInfo

    The fees associated with the transfer of token1 (second token) in the exchange/settlement of the token pair. throws FrictionlessTransferManagerInvalidTokenAddresses if the token addresses are invalid. throws AbstractFeeModuleInvalidFeeRecipient if the feeRecipientAddr is a zero address throws AbstractFeeModuleInvalidFee if the feeInBps is not in the valid range (ZERO_FEES_IN_BPS to MAX_FEES_IN_BPS) emits FrictionlessTokenFeeSet upon completion of the setting of the fee info for the token in either set of fees

    hashtag
    setTokenFee

    Set the fee associated with the transfer of a Token and manages the mapping of the key to this set of Fees. Can only be set by the Owner (PROTOCOL_ADMIN).

    Parameters

    Name
    Type
    Description

    tokenFeeKey_

    bytes32

    the key, generated by the function getTokenFeeKey, which is used to map a specific transfer polarity for tokens.

    tokenFeeInfo_

    TokenFeeInfo

    The fees associated with the transfer of token, used in the calculation and disbursement of fees during exchange/settlement of a token pair. throws FrictionlessTransferManagerInvalidTokenAddresses if the token addresses are invalid. throws AbstractFeeModuleInvalidFeeRecipient if the feeRecipientAddr is a zero address throws AbstractFeeModuleInvalidFee if the feeInBps is not in the valid range (ZERO_FEES_IN_BPS to MAX_FEES_IN_BPS) emits FrictionlessTokenFeeSet upon completion of the setting of the fee info for the token

    hashtag
    exchangeTokens

    Executes a token pair exchange. This function can only be invoked by the PROTOCOL_TREASURY

    Parameters

    Name
    Type
    Description

    token0TransferData_

    TokenTransferData

    the transfer data for the first token in the exchange

    token1TransferData_

    TokenTransferData

    the transfer data for the second token in the exchange throws FrictionlessTransferManagerNotEnoughTokens if the balance of any of the tokens held by any users in the transfer is below the transfer amount throws FrictionlessTransferManagerInvalidTokenAddresses if any of the token addresses are zero. throws FrictionlessTransferManagerZeroAmount if any of the token amounts are zero throws FrictionlessTransferManagerInvalidTokenSenderAddresses if the expectedToken0Sender_ is not the same as the token0TransferData_.tokenSender throws FrictionlessTransferManagerInvalidTokenSenderAddresses if the token1TransferData_.tokenSender is a zero address emits FrictionlessTokensExchanged upon successful exchange.

    hashtag
    createTransferOffer

    Initiates/Creates a transferOffer between a token pair exchange. Setting the transfer status to PENDING for state management of the overall transfer. This function generates a transferOfferId_ which is returned so invokers of the function can perform further functions such as confirmTransferOffer or cancelOffer.

    Parameters

    Name
    Type
    Description

    token0TransferData_

    TokenTransferData

    the transfer data for the first token in the exchange

    token1TransferData_

    TokenTransferData

    the transfer data for the second token in the exchange

    Returns

    Name
    Type
    Description

    <none>

    uint256

    transferOfferId_ representing the stored transfer in this contract for future operations such as confirmTransferOffer or cancelOffer. throws FrictionlessTransferManagerNotEnoughTokens if the balance of any of the tokens held by any users in the transfer is below the transfer amount throws FrictionlessTransferManagerInvalidTokenAddresses if any of the token addresses are zero. throws FrictionlessTransferManagerZeroAmount if any of the token amounts are zero throws FrictionlessTransferManagerInvalidTokenSenderAddresses if the expectedToken0Sender_ is not the same as the token0TransferData_.tokenSender throws FrictionlessTransferManagerInvalidTokenSenderAddresses if the token1TransferData_.tokenSender is a zero address emits FrictionlessTransferOfferCreated upon successful offer created.

    hashtag
    redeemTokens

    Redeem/Burn an amount for tokens for the specified tokenAddr_ and msg.sender

    Parameters

    Name
    Type
    Description

    tokenAddr_

    address

    the address of the token

    redeemAmount_

    uint256

    the amount of the token to burn (redeem) throws FrictionlessTransferManagerZeroAddress if the token address or the msg.sender is a zero address throws FrictionlessTransferManagerZeroAmount if the redeemAmount_ is zero throws FrictionlessTransferManagerNotEnoughTokens if the balance of a user for a given token is below the redeemAmount_ emits FrictionlessTokensRedeemed when the burn has occurred

    hashtag
    redeemERC20Tokens

    Redeem/Burn an amount for tokens for the specified ERC20 tokenAddr_ and msg.sender, this will convert the ERC20 token to a FrictionlessFundDepositToken first, then redeem See {IFrictionlessERC20ConverterManager-isTokenSupported} {IFrictionlessERC20ConverterManager-convertFromERC20}

    Parameters

    Name
    Type
    Description

    erc20Token_

    address

    the address of the ERC20 token

    fundDepositToken_

    address

    the address of the FundDeposit token

    tokenRedeemAmount_

    uint256

    the amount of the token to convert & burn (redeem) throws FrictionlessTransferManagerZeroAddress if the token address or the msg.sender is a zero address throws FrictionlessTransferManagerZeroAmount if the tokenRedeemAmount_ is zero throws FrictionlessTransferManagerNotEnoughTokens if the balance of a user for a given token is below the tokenRedeemAmount_ throws FrictionlessTransferManagerInvalidERC20TokenForRedeem if the tokenAddr_ is noy a valid convertible ERC20 token emits FrictionlessTokensRedeemed when the burn has occurred

    hashtag
    redeemTokensFrom

    Redeem/Burn an amount for tokens for the specified tokenAddr_ and userAddr_. This function can only be invoked by the PROTOCOL_TREASURY

    Parameters

    Name
    Type
    Description

    tokenAddr_

    address

    the address of the token

    userAddr_

    address

    the address of the holder of the token

    redeemAmount_

    uint256

    the amount of the token to burn (redeem) throws FrictionlessTransferManagerZeroAddress if the token address or the userAddr_ is a zero address throws FrictionlessTransferManagerZeroAmount if the redeemAmount_ is zero throws FrictionlessTransferManagerNotEnoughTokens if the balance of a user for a given token is below the redeemAmount_ emits FrictionlessTokensRedeemed when the burn has occurred

    hashtag
    redeemERC20TokensFrom

    Redeem/Burn an amount for tokens for the specified ERC20 tokenAddr_ and userAddr_. This will convert the ERC20 token to a FrictionlessFundDepositToken first, then reedem. This function can only be invoked by the PROTOCOL_TREASURY See {IFrictionlessERC20ConverterManager-isTokenSupported} {IFrictionlessERC20ConverterManager-convertFromERC20}

    Parameters

    Name
    Type
    Description

    erc20Token_

    address

    the address of the ERC20 token

    fundDepositToken_

    address

    the address of the FundDeposit token

    userAddr_

    address

    the address of the holder of the token

    hashtag
    confirmTransferOffer

    Confirms and processes the transfer for the respective transferOfferId_, which results int he compliant token transfers under ERC-3643 specification to occur.

    Parameters

    Name
    Type
    Description

    transferOfferId_

    uint256

    the id of the transfer returned/emitted in the function createTransferOffer Requires the transfer status is TransferStatuses.PENDING throws FrictionlessTransferManagerInvalidTransferStatus if the transfer status is NOT TransferStatuses.PENDING throws FrictionlessTransferManagerNotEnoughPermissions If the msg.sender is not the tokenSender of the second token in the exchange or if the msg.sender is not a valid TREX Agent of either toekns in the exchange. emits FrictionlessTransferOfferConfirmed upon successful completion of the transfers.

    hashtag
    cancelTransferOffer

    Cancels a transfer for the given transferOfferId_, which results in the transfer status being set to TransferStatuses.CANCELED and the relevant FrictionlessTransferOfferCanceled being emitted.

    Parameters

    Name
    Type
    Description

    transferOfferId_

    uint256

    the generated transferOfferId_ used to store the state of transfers in the contract. requires the Transfer to be in a PENDING state. throws FrictionlessTransferManagerInvalidTransferStatus if the transfer status is NOT TransferStatuses.PENDING throws FrictionlessTransferManagerNotEnoughPermissions If the msg.sender is not the tokenSender of the second token in the exchange or if the msg.sender is not a valid TREX Agent of either tokens in the exchange.

    hashtag
    nextTransferOfferId

    Generates the next transferOfferId in the smart contract, used to store state of a transfer.

    Returns

    Name
    Type
    Description

    <none>

    uint256

    the next transferOfferId in the smart contract, used to store state of a transfer.

    hashtag
    minRedeemAmount

    Get the minimum redemption amount configured

    Returns

    Name
    Type
    Description

    <none>

    uint256

    minimum redemption amount, to ensure there is meaningful settlement amounts, generally this is used to ensure FIAT transfers are above a minimum banking threshold, such as 1 USD.

    hashtag
    getTransferData

    Returns the transfer data stored for the given transferOfferId_

    Parameters

    Name
    Type
    Description

    transferOfferId_

    uint256

    the generated transferOfferId_ used to store the state of transfers in the contract

    Returns

    Name
    Type
    Description

    <none>

    TransferData

    TransferData, the transfer data for the given transferOfferId_

    hashtag
    getTransferFeesInfo

    get the tokenFeeInfo set for the fees associated per token in an exchange.

    Parameters

    Name
    Type
    Description

    token0_

    address

    the address of the first token in an exchange

    token1_

    address

    the address of the second token in an exchange

    Returns

    Name
    Type
    Description

    <none>

    FeeInfo

    FeeInfo set for the fees associated per token in an exchange.

    <none>

    FeeInfo

    hashtag
    getTransferFeeKeys

    Generates keys based on the packed encoding of the addresses of sets of tokens using the keccak256 hashing function. Used to store tokenFees in mappings.

    Parameters

    Name
    Type
    Description

    token0_

    address

    the address of the token 0 in a transfer fee calculation

    token1_

    address

    the address of the token 1 in a transfer fee calculation

    Returns

    Name
    Type
    Description

    <none>

    bytes32

    keys based on the packed encoding of the addresses of sets of tokens using the keccak256 hashing function.

    <none>

    bytes32

    hashtag
    getTokenFeeKey

    Generates a key based on the packed encoding of the addresses of both tokens using the keccak256 hashing function. Used to store tokenFees in mappings.

    Parameters

    Name
    Type
    Description

    token0_

    address

    the address of the token 0 in a transfer fee calculation

    token1_

    address

    the address of the token 1 in a transfer fee calculation

    Returns

    Name
    Type
    Description

    <none>

    bytes32

    generates a key based on the packed encoding of the addresses of both tokens using the keccak256 hashing function.

    hashtag
    Events

    hashtag
    FrictionlessTransferOfferCreated

    Event emitted during createTransferOffer

    hashtag
    FrictionlessTransferOfferConfirmed

    Event emitted during confirmTransferOffer

    hashtag
    FrictionlessTransferOfferCanceled

    Event emitted during cancelOffer

    hashtag
    FrictionlessTokensExchanged

    Event emitted during exchangeTokens

    hashtag
    FrictionlessTokensRedeemed

    Event emitted during redeemTokens and redeemTokensFrom

    hashtag
    Errors

    hashtag
    FrictionlessTransferManagerInvalidTokenAddresses

    error thrown during setTransferFees, setTransferFees, exchangeTokens or createTransferOffer if any of the token addresses are zero.

    hashtag
    FrictionlessTransferManagerInvalidTokenSenderAddresses

    error thrown during exchangeTokens or createTransferOffer if any of the tokenSender address in an exchange is a zero address

    hashtag
    FrictionlessTransferManagerInvalidTokensPairForRedeem

    hashtag
    FrictionlessTransferManagerCannotTransferToken

    error thrown during createTransferOffer if the token transfer is prohibited under Compliance contract rules

    hashtag
    FrictionlessTransferManagerZeroAddress

    error thrown during redeemTokens or redeemTokensFrom if the token address or the msg.sender is a zero address

    hashtag
    FrictionlessTransferManagerZeroAmount

    error thrown during exchangeTokens, createTransferOffer, redeemTokens or redeemTokensFrom if any of the token amounts are zero

    hashtag
    FrictionlessTransferManagerRedeemAmountIsLessThanMinimum

    error thrown when the redemption amount is below the configured minimum, during redeemTokens or redeemERC20Tokens

    hashtag
    FrictionlessTransferManagerNotEnoughTokens

    error thrown during exchangeTokens, createTransferOffer, redeemTokens or redeemTokensFrom if the balance of any of the tokens held by any users in the transfer is below the transfer amount

    hashtag
    FrictionlessTransferManagerInvalidTransferStatus

    error thrown during confirmTransferOffer or cancelOffer if the transfer status expectedStatus does not match the actualStatus

    hashtag
    FrictionlessTransferManagerNotEnoughPermissions

    error thrown during createTransferOffer or confirmTransferOffer if any of the msg.sender is not an Agent of the tokens in the transfer.

    hashtag
    Structs

    hashtag
    TokenFeeInfo

    TokenFeeInfo represents the fee (zero or otherwise) that is associated with the transfer of a token in the Transfer Manager exchange.

    hashtag
    TokenTransferData

    TokenTransferData represents the data set in a transfer of a token

    hashtag
    TransferData

    TransferData represents a maker/taker model of transfer, where 1 token is exchanged for another

    hashtag
    Enums

    hashtag
    TransferStatuses

    Enumeration to track transfer statuses

    Git Sourcearrow-up-right
    function updateMinRedeemAmount(uint256 newMinRedeemAmount_) external;
    function setTransferFees(TokenFeeInfo calldata token0FeeInfo_, TokenFeeInfo calldata token1FeeInfo_) external;
    function setTokenFee(bytes32 tokenFeeKey_, TokenFeeInfo calldata tokenFeeInfo_) external;
    function exchangeTokens(TokenTransferData memory token0TransferData_, TokenTransferData memory token1TransferData_)
        external;
    function createTransferOffer(TokenTransferData memory token0TransferData_, TokenTransferData memory token1TransferData_)
        external
        returns (uint256);
    function redeemTokens(address tokenAddr_, uint256 redeemAmount_) external;
    function redeemERC20Tokens(address erc20Token_, address fundDepositToken_, uint256 tokenRedeemAmount_) external;
    function redeemTokensFrom(address tokenAddr_, address userAddr_, uint256 redeemAmount_) external;
    function redeemERC20TokensFrom(
        address erc20Token_,
        address fundDepositToken_,
        address userAddr_,
        uint256 tokenRedeemAmount_
    ) external;
    function confirmTransferOffer(uint256 transferOfferId_) external;
    function cancelTransferOffer(uint256 transferOfferId_) external;
    function nextTransferOfferId() external view returns (uint256);
    function minRedeemAmount() external view returns (uint256);
    function getTransferData(uint256 transferOfferId_) external view returns (TransferData memory);
    function getTransferFeesInfo(address token0_, address token1_) external view returns (FeeInfo memory, FeeInfo memory);
    function getTransferFeeKeys(address token0_, address token1_) external view returns (bytes32, bytes32);
    function getTokenFeeKey(address token0_, address token1_) external view returns (bytes32);
    event FrictionlessTransferOfferCreated(uint256 transferId);
    event FrictionlessTransferOfferConfirmed(uint256 transferId);
    event FrictionlessTransferOfferCanceled(uint256 transferId);
    event FrictionlessTokensExchanged(TokenTransferData token0TransferData, TokenTransferData token1TransferData);
    event FrictionlessTokensRedeemed(address tokenAddr, address userAddr, uint256 redeemAmount);
    error FrictionlessTransferManagerInvalidTokenAddresses(address token0, address token1);
    error FrictionlessTransferManagerInvalidTokenSenderAddresses(address token0Sender, address token1Sender);
    error FrictionlessTransferManagerInvalidTokensPairForRedeem(address erc20Token, address funDepositToken);
    error FrictionlessTransferManagerCannotTransferToken(address tokenAddr, address from, address to, uint256 amount);
    error FrictionlessTransferManagerZeroAddress();
    error FrictionlessTransferManagerZeroAmount();
    error FrictionlessTransferManagerRedeemAmountIsLessThanMinimum(uint256 redeemAmount);
    error FrictionlessTransferManagerNotEnoughTokens(address tokenAddr, address userAddr, uint256 tokensToTransfer);
    error FrictionlessTransferManagerInvalidTransferStatus(TransferStatuses expectedStatus, TransferStatuses actualStatus);
    error FrictionlessTransferManagerNotEnoughPermissions();
    struct TokenFeeInfo {
        address tokenAddr;
        FeeInfo feeInfo;
    }
    struct TokenTransferData {
        address tokenAddr;
        address tokenSender;
        uint256 tokenAmount;
    }
    struct TransferData {
        TokenTransferData token0Data;
        TokenTransferData token1Data;
        uint256 feeInBps0;
        uint256 feeInBps1;
        TransferStatuses status;
    }
    enum TransferStatuses {
        NONE,
        PENDING,
        CONFIRMED,
        CANCELED
    }

    tokenRedeemAmount_

    uint256

    the amount of the token to convert and burn (redeem) throws FrictionlessTransferManagerZeroAddress if the token address or the userAddr_ is a zero address throws FrictionlessTransferManagerZeroAmount if the tokenRedeemAmount_ is zero throws FrictionlessTransferManagerNotEnoughTokens if the balance of a user for a given token is below the tokenRedeemAmount_ throws FrictionlessTransferManagerInvalidERC20TokenForRedeem if the tokenAddr_ is noy a valid convertible ERC20 token emits FrictionlessTokensRedeemed when the burn has occurred

    IFrictionlessAttestationManager

    Git Sourcearrow-up-right

    Author: DEFYCA Labs S.à.r.l

    Copyright © 2023 DEFYCA Labs S.à.r.l Permission is hereby granted, free of charge, to any person obtaining a copy of the Frictionless protocol smart contracts (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL DEFYCA LABS S.à.r.l BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

    The IFrictionlessAttestationManager See the flow and description of the attestation workflow in the diagram at https://gitlab.com/dfyclabs/protocol/dfyclabs-tokens/-/raw/main/docs/img/frictionless-fund-deposit-flow-attestation.png

    hashtag
    Functions

    hashtag
    updateAttestationToken

    Update the token address of the FrictionlessFundDepositToken for the currency_ and iban_ pair.

    Parameters

    Name
    Type
    Description

    hashtag
    confirmAttestation

    Confirm the attestation by signing the signature, this is the proof of the attestation by the PERMISSIONED_FUND_ACCOUNTANT

    Parameters

    Name
    Type
    Description

    hashtag
    minBalance

    Get the minimum balance amount configured, for which an attestation can be run. If the balance of the attestation is below the value configured, the error will be thrown. The minimum allowed is 10_000 or 0.01

    Returns

    Name
    Type
    Description

    hashtag
    minWindow

    Get minimum time (reportEnd - reportStart) in blocktime for which an attestation can be run. Typically this is 1 hour, and dependent on the availability of transaction data in the underlying fund account as specified by the IBAN. The minimum allowed is 300 seconds.

    Returns

    Name
    Type
    Description

    hashtag
    maxWindow

    Get maximum time (reportEnd - reportStart) in blocktime for which an attestation can be run. Typically this is 30 days, aligned with the reporting as per regulation for the underlying fund and issuer of the deposit token. The maximum allowed is 365 days.

    Returns

    Name
    Type
    Description

    hashtag
    getAccountAttestationDataKeys

    Retrieves the keys of attestation data associated with a specific account identified by IBAN and currency.

    Parameters

    Name
    Type
    Description

    Returns

    Name
    Type
    Description

    hashtag
    getAccountLastAttestationData

    Retrieves the last attestation data associated with a specific account identified by IBAN and currency.

    Parameters

    Name
    Type
    Description

    Returns

    Name
    Type
    Description

    hashtag
    getAccountLastAttestationDataKey

    Retrieves the key of the last attestation data associated with a specific account identified by IBAN and currency.

    Parameters

    Name
    Type
    Description

    Returns

    Name
    Type
    Description

    hashtag
    getAttestationData

    Retrieves attestation data by the attestation data key.

    Parameters

    Name
    Type
    Description

    Returns

    Name
    Type
    Description

    hashtag
    getTokenAddress

    Get the valid FrictionlessFundDepositToken for the currency_ and iban_ pair.

    Parameters

    Name
    Type
    Description

    Returns

    Name
    Type
    Description

    hashtag
    getAttestationDataHash

    Mint a new attestation, it returns hash of attestation data to sign by the PERMISSIONED_FUND_ACCOUNTANT

    Parameters

    Name
    Type
    Description

    Returns

    Name
    Type
    Description

    hashtag
    getAccountAttestationKey

    Retrieves the attestation data key associated with a specific account identified by currency and IBAN.

    Parameters

    Name
    Type
    Description

    Returns

    Name
    Type
    Description

    hashtag
    Events

    hashtag
    FrictionlessFundDepositAttestationTokenUpdated

    Emitted when the FrictionlessFundDepositToken is updated in the IFrictionlessAttestationManager.

    hashtag
    FrictionlessFundDepositAttestationConfirmed

    Event emitted upon the confirmation of a FrictionlessFundDepositToken in the IFrictionlessAttestationManager

    hashtag
    Errors

    hashtag
    FrictionlessAttestationManagerCallerNotAProtocolTreasury

    thrown if msg.sender address is not a PROTOCOL_TREASURY, during updateAttestationToken

    hashtag
    FrictionlessAttestationManagerTokenZeroAddress

    thrown if tokenAddress_ address is a zero address, during updateAttestationToken

    hashtag
    FrictionlessAttestationManagerPermissionsZeroAddress

    thrown if permissionManagerAddr_ address is a zero address, during init

    hashtag
    FrictionlessAttestationManagerInvalidToken

    thrown if the FrictionlessFundDepositToken has not been registered for the IBAN, currency pair.

    hashtag
    FrictionlessAttestationManagerInvalidReport

    thrown if the passed AttestationData report is invalid.

    hashtag
    FrictionlessAttestationManagerBalanceTooLow

    thrown if the attestation balance is too small, below the configurable amount.

    hashtag
    FrictionlessAttestationManagerDuplicateLastTxHash

    thrown if the last transaction hash for the attestation has already been used, this avoids duplicate attestations.

    hashtag
    FrictionlessAttestationManagerInvalidAttestationSigner

    thrown if the attestation cannot be confirmed, meaning the signed attestation cannot be verified.

    hashtag
    Structs

    hashtag
    AttestationData

    struct to hold attestation data, which is designed to provide the most recent attestation of balance and verified last transaction in an attestation window.

    hashtag
    AccountAttestationData

    struct to hold account attestation data

    tokenAddress_

    address

    the address of deposit FrictionlessFundDepositToken

    iban_

    string

    the IBAN associated with the FrictionlessFundDepositToken

    currency_

    string

    the currency associated with the FrictionlessFundDepositToken throws FrictionlessAttestationManagerTokenZeroAddress if tokenAddress_ address is a zero address emits FrictionlessFundDepositAttestationTokenUpdated upon successful updating

    attestationData_

    AttestationData

    attestation data to sign

    sig_

    bytes

    the signature to sign by the PERMISSIONED_FUND_ACCOUNTANT throws FrictionlessAttestationManagerNotEnoughPermissions if the msg.sender does not have the role PERMISSIONED_FUND_ACCOUNTANT throws FrictionlessAttestationManagerInvalidAttestation if the attestation cannot be confirmed, meaning the signed attestation cannot be verified. emits FrictionlessFundDepositAttestationConfirmed upon successful signing

    <none>

    uint256

    minimum attestation balance.

    <none>

    uint256

    minimum attestation window.

    <none>

    uint256

    maximum attestation window.

    iban_

    string

    the IBAN associated with the FrictionlessFundDepositToken

    currency_

    string

    the currency associated with the FrictionlessFundDepositToken

    <none>

    bytes32[]

    the array of bytes32 attestation data keys associated with the account.

    iban_

    string

    the IBAN associated with the FrictionlessFundDepositToken

    currency_

    string

    the currency associated with the FrictionlessFundDepositToken

    <none>

    AttestationData

    the AttestationData struct representing the last attestation data associated with the account.

    iban_

    string

    the IBAN associated with the FrictionlessFundDepositToken

    currency_

    string

    the currency associated with the FrictionlessFundDepositToken

    <none>

    bytes32

    the last attestation data key associated with the account.

    attestationDataKey_

    bytes32

    the key identifying the attestation data

    <none>

    AttestationData

    the AttestationData struct representing the attestation data associated with the given key.

    iban_

    string

    the IBAN associated with the FrictionlessFundDepositToken

    currency_

    string

    the currency associated with the FrictionlessFundDepositToken

    <none>

    address

    the address of the valid FrictionlessFundDepositToken for the currency_ and iban_ pair

    attestationData_

    AttestationData

    the complete set of attestation data to for the PERMISSIONED_FUND_ACCOUNTANT to certify/sign.

    <none>

    bytes32

    a hash of the attestationData which will be signed to confirm the attestation

    currency_

    string

    the currency associated with the FrictionlessFundDepositToken

    iban_

    string

    the IBAN associated with the FrictionlessFundDepositToken

    <none>

    bytes32

    the accound attestation key.

    function updateAttestationToken(address tokenAddress_, string calldata iban_, string calldata currency_) external;
    function confirmAttestation(AttestationData calldata attestationData_, bytes calldata sig_) external;
    function minBalance() external view returns (uint256);
    function minWindow() external view returns (uint256);
    function maxWindow() external view returns (uint256);
    function getAccountAttestationDataKeys(string calldata iban_, string calldata currency_)
        external
        view
        returns (bytes32[] memory);
    function getAccountLastAttestationData(string calldata iban_, string calldata currency_)
        external
        view
        returns (AttestationData memory);
    function getAccountLastAttestationDataKey(string calldata iban_, string calldata currency_)
        external
        view
        returns (bytes32);
    function getAttestationData(bytes32 attestationDataKey_) external view returns (AttestationData memory);
    function getTokenAddress(string memory iban_, string memory currency_) external view returns (address);
    function getAttestationDataHash(AttestationData calldata attestationData_) external view returns (bytes32);
    function getAccountAttestationKey(string calldata currency_, string calldata iban_) external pure returns (bytes32);
    event FrictionlessFundDepositAttestationTokenUpdated(
        bytes32 accountAttestationKey, address newTokenAddress, address oldTokenAddress
    );
    event FrictionlessFundDepositAttestationConfirmed(AttestationData attestationData);
    error FrictionlessAttestationManagerCallerNotAProtocolTreasury(address caller);
    error FrictionlessAttestationManagerTokenZeroAddress();
    error FrictionlessAttestationManagerPermissionsZeroAddress();
    error FrictionlessAttestationManagerInvalidToken(string iban, string currency);
    error FrictionlessAttestationManagerInvalidReport(AttestationData attestationData);
    error FrictionlessAttestationManagerBalanceTooLow(uint256 balance);
    error FrictionlessAttestationManagerDuplicateLastTxHash(string lastTxHash);
    error FrictionlessAttestationManagerInvalidAttestationSigner(address signer, bytes32 attestationHash, bytes sig);
    struct AttestationData {
        address tokenAddr;
        string iban;
        string currency;
        uint256 reportStart;
        uint256 reportEnd;
        uint256 balance;
        string lastTxHash;
    }
    struct AccountAttestationData {
        address attestationTokenAddr;
        bytes32 lastAttestationDataKey;
        EnumerableSet.Bytes32Set allAttestationDataKeys;
    }