# IFrictionlessTransferManager

[Git Source](https://gitlab.com/dfyclabs/protocol/dfyclabs-tokens/blob/85f6dfa54ce0787eb1b1345bd6726f84fe766c54/contracts/interface/IFrictionlessTransferManager.sol)

**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>

## Functions

### 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.*

```solidity
function updateMinRedeemAmount(uint256 newMinRedeemAmount_) external;
```

**Parameters**

| Name                  | Type      | Description                                                                                                                 |
| --------------------- | --------- | --------------------------------------------------------------------------------------------------------------------------- |
| `newMinRedeemAmount_` | `uint256` | the minimum redemption amount, if not reached , typically throws `FrictionlessTransferManagerRedeemAmountIsLessThanMinimum` |

### 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).*

```solidity
function setTransferFees(TokenFeeInfo calldata token0FeeInfo_, TokenFeeInfo calldata token1FeeInfo_) external;
```

**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 |

### 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).*

```solidity
function setTokenFee(bytes32 tokenFeeKey_, TokenFeeInfo calldata tokenFeeInfo_) external;
```

**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 |

### exchangeTokens

*Executes a token pair exchange. This function can only be invoked by the PROTOCOL\_TREASURY*

```solidity
function exchangeTokens(TokenTransferData memory token0TransferData_, TokenTransferData memory token1TransferData_)
    external;
```

**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. |

### 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`.*

```solidity
function createTransferOffer(TokenTransferData memory token0TransferData_, TokenTransferData memory token1TransferData_)
    external
    returns (uint256);
```

**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. |

### redeemTokens

*Redeem/Burn an amount for tokens for the specified tokenAddr\_ and `msg.sender`*

```solidity
function redeemTokens(address tokenAddr_, uint256 redeemAmount_) external;
```

**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 |

### 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}*

```solidity
function redeemERC20Tokens(address erc20Token_, address fundDepositToken_, uint256 tokenRedeemAmount_) external;
```

**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 |

### redeemTokensFrom

*Redeem/Burn an amount for tokens for the specified tokenAddr\_ and userAddr\_. This function can only be invoked by the PROTOCOL\_TREASURY*

```solidity
function redeemTokensFrom(address tokenAddr_, address userAddr_, uint256 redeemAmount_) external;
```

**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 |

### 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}*

```solidity
function redeemERC20TokensFrom(
    address erc20Token_,
    address fundDepositToken_,
    address userAddr_,
    uint256 tokenRedeemAmount_
) external;
```

**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                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `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 |

### confirmTransferOffer

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

```solidity
function confirmTransferOffer(uint256 transferOfferId_) external;
```

**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. |

### 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.*

```solidity
function cancelTransferOffer(uint256 transferOfferId_) external;
```

**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. |

### nextTransferOfferId

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

```solidity
function nextTransferOfferId() external view returns (uint256);
```

**Returns**

| Name     | Type      | Description                                                                        |
| -------- | --------- | ---------------------------------------------------------------------------------- |
| `<none>` | `uint256` | the next transferOfferId in the smart contract, used to store state of a transfer. |

### minRedeemAmount

*Get the minimum redemption amount configured*

```solidity
function minRedeemAmount() external view returns (uint256);
```

**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. |

### getTransferData

*Returns the transfer data stored for the given transferOfferId\_*

```solidity
function getTransferData(uint256 transferOfferId_) external view returns (TransferData memory);
```

**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\_ |

### getTransferFeesInfo

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

```solidity
function getTransferFeesInfo(address token0_, address token1_) external view returns (FeeInfo memory, FeeInfo memory);
```

**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` |                                                               |

### 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.*

```solidity
function getTransferFeeKeys(address token0_, address token1_) external view returns (bytes32, bytes32);
```

**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` |                                                                                                            |

### 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.*

```solidity
function getTokenFeeKey(address token0_, address token1_) external view returns (bytes32);
```

**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. |

## Events

### FrictionlessTransferOfferCreated

*Event emitted during `createTransferOffer`*

```solidity
event FrictionlessTransferOfferCreated(uint256 transferId);
```

### FrictionlessTransferOfferConfirmed

*Event emitted during `confirmTransferOffer`*

```solidity
event FrictionlessTransferOfferConfirmed(uint256 transferId);
```

### FrictionlessTransferOfferCanceled

*Event emitted during `cancelOffer`*

```solidity
event FrictionlessTransferOfferCanceled(uint256 transferId);
```

### FrictionlessTokensExchanged

*Event emitted during `exchangeTokens`*

```solidity
event FrictionlessTokensExchanged(TokenTransferData token0TransferData, TokenTransferData token1TransferData);
```

### FrictionlessTokensRedeemed

*Event emitted during `redeemTokens` and `redeemTokensFrom`*

```solidity
event FrictionlessTokensRedeemed(address tokenAddr, address userAddr, uint256 redeemAmount);
```

## Errors

### FrictionlessTransferManagerInvalidTokenAddresses

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

```solidity
error FrictionlessTransferManagerInvalidTokenAddresses(address token0, address token1);
```

### FrictionlessTransferManagerInvalidTokenSenderAddresses

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

```solidity
error FrictionlessTransferManagerInvalidTokenSenderAddresses(address token0Sender, address token1Sender);
```

### FrictionlessTransferManagerInvalidTokensPairForRedeem

```solidity
error FrictionlessTransferManagerInvalidTokensPairForRedeem(address erc20Token, address funDepositToken);
```

### FrictionlessTransferManagerCannotTransferToken

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

```solidity
error FrictionlessTransferManagerCannotTransferToken(address tokenAddr, address from, address to, uint256 amount);
```

### FrictionlessTransferManagerZeroAddress

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

```solidity
error FrictionlessTransferManagerZeroAddress();
```

### FrictionlessTransferManagerZeroAmount

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

```solidity
error FrictionlessTransferManagerZeroAmount();
```

### FrictionlessTransferManagerRedeemAmountIsLessThanMinimum

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

```solidity
error FrictionlessTransferManagerRedeemAmountIsLessThanMinimum(uint256 redeemAmount);
```

### 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*

```solidity
error FrictionlessTransferManagerNotEnoughTokens(address tokenAddr, address userAddr, uint256 tokensToTransfer);
```

### FrictionlessTransferManagerInvalidTransferStatus

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

```solidity
error FrictionlessTransferManagerInvalidTransferStatus(TransferStatuses expectedStatus, TransferStatuses actualStatus);
```

### FrictionlessTransferManagerNotEnoughPermissions

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

```solidity
error FrictionlessTransferManagerNotEnoughPermissions();
```

## Structs

### TokenFeeInfo

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

```solidity
struct TokenFeeInfo {
    address tokenAddr;
    FeeInfo feeInfo;
}
```

### TokenTransferData

*TokenTransferData represents the data set in a transfer of a token*

```solidity
struct TokenTransferData {
    address tokenAddr;
    address tokenSender;
    uint256 tokenAmount;
}
```

### TransferData

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

```solidity
struct TransferData {
    TokenTransferData token0Data;
    TokenTransferData token1Data;
    uint256 feeInBps0;
    uint256 feeInBps1;
    TransferStatuses status;
}
```

## Enums

### TransferStatuses

*Enumeration to track transfer statuses*

```solidity
enum TransferStatuses {
    NONE,
    PENDING,
    CONFIRMED,
    CANCELED
}
```
