Fraction ProtocolgenericFacetsfundingPacketFacetfundingErc20Packets

FundingErc20PacketsFacetStorage

This library manages the storage and logic for handling the configuration of funding packets for campaigns and facilitates their transfer.

_This implementation is designed for use in campaigns where the funding packet is constructed solely from ERC20 tokens.

IMPORTANT:

  • Extra care should be taken when specifying token amounts, especially when dealing with tokens of varying decimal precision.
  • A funding packet can encapsulate one (e.g., tokenA) or more (e.g., tokenA, tokenB, ..., tokenX) ERC20 tokens.

NOTE:

  • We do not use the custom:storage-location annotation because the Layout struct is defined in a library, which, as of now, does not support automated storage layout validation. However, the implementation adheres to the ERC-7201 structure in spirit by ensuring unique and collision-free storage slots using the ERC-7201 formula._

NoInitFundingPacketDataProvided

error NoInitFundingPacketDataProvided()

Thrown at initializer when no data provided for tokenAddresses.

NoFundingPacketDataProvided

error NoFundingPacketDataProvided(uint256 campaignId)

Thrown at setter when no data provided for either tokenAddresses or amountOfTokensPerPacket.

InvalidFundingPacketDataLengths

error InvalidFundingPacketDataLengths(uint256 campaignId, uint256 tokenAddressesLength, uint256 amountOfTokensPerPacketLength)

Thrown at setter when the lengths of tokenAddresses and amountOfTokensPerPacket do not match.

InvalidZeroFundingPacketAddressData

error InvalidZeroFundingPacketAddressData(uint256 campaignId, uint256 index)

Thrown at setter when an element of tokenAddresses is the zero address.

InvalidZeroFundingPacketAmountData

error InvalidZeroFundingPacketAmountData(uint256 campaignId, uint256 index)

Thrown at setter when an element of amountOfTokensPerPacket is zero.

AlreadyImportedTokenAddress

error AlreadyImportedTokenAddress(uint256 campaignId, address tokenAddress)

Thrown when trying to import a funding token address that has already been imported.

TokenAddressNotAllowed

error TokenAddressNotAllowed(uint256 campaignId, address tokenAddress)

Thrown when trying to import a funding token address that is not allowed.

InvalidTokenAddress

error InvalidTokenAddress(address tokenAddress)

Thrown when trying to import an incorrect funding token address. (ex. not an ERC20 token or wrong address)

AlreadyAcceptedTokenAddress

error AlreadyAcceptedTokenAddress(address tokenAddress)

Thrown when trying to accept a funding token address that has already been accepted.

TokenAddressWasNotAccepted

error TokenAddressWasNotAccepted(address tokenAddress)

Thrown when trying to remove a funding token address that was not accepted.

STORAGE_SLOT

bytes32 STORAGE_SLOT

Unique identifier for the storage slot where the Layout struct is stored. Derived from the ERC7201 formula.

Layout

Struct for managing information related to campaigns' funding packets.

struct Layout {
  mapping(uint256 => struct FundingErc20PacketsFacetStorage.FundingPacket) campaignsPacketInfo;
  mapping(address => bool) acceptedFundingTokens;
}

FundingPacket

Struct containing the configuration information for an funding packet.

struct FundingPacket {
  address[] tokenAddresses;
  mapping(address => uint256) amountOfTokensPerPacket;
  mapping(address => bool) isTokenAddressImported;
}

layout

function layout() internal pure returns (struct FundingErc20PacketsFacetStorage.Layout l)

Retrieves a reference to the Layout struct stored at the slot specified by STORAGE_SLOT unique identifier.

initFundingErc20PacketFacet

function initFundingErc20PacketFacet(struct FundingErc20PacketsFacetStorage.Layout l, bytes initFundingPacketData) internal returns (address[])

Initializes the FundingErc20PacketsFacetStorage by setting the approved ERC20 tokens. If a token is already imported, AlreadyImportedTokenAddress error is thrown.

These tokens serve as valid funding currencies within the platform.

Parameters

NameTypeDescription
lstruct FundingErc20PacketsFacetStorage.Layout
initFundingPacketDatabytesThe ABI-encoded data containing the following: approvedTokens: An array of ERC20 token addresses approved for inclusion in input packets.

setAndCheckFundingPacket

function setAndCheckFundingPacket(struct FundingErc20PacketsFacetStorage.Layout l, bytes postFractionFundingPacketData) internal returns (uint256, address[], uint256[])

Configures and validates the funding packet of a campaign.

_Set and Check functions are executed during the creation process of campaigns (see CreateFractionsSkeleton.sol).

This function configures the funding packet for a campaign, where only ERC20 tokens should be included.

Requirements:

  • The tokenAddresses and amountOfTokensPerPacket arrays must have the same length.
  • tokenAddresses must contain approved ERC20 token addresses.
  • amountOfTokensPerPacket must contain non-zero values.

IMPORTANT:

  • If all ERC20 tokens in tokenAddresses have the same decimal places, two configuration options exist:

    1. Parse values in amountOfTokensPerPacket using the common decimal precision (wei values). In this case, funding packet amounts should be specified in whole units at the API level. This option is only viable when no Discount & no Interest mechanisms are featured in the campaign.

    2. Specify values in amountOfTokensPerPacket in whole units, thus, funding packet amounts should be parsed with the appropriate number of decimal digits at the API level (e.g., in BuybackSekelton.buyback() etc.).

  • If any ERC20 token in tokenAddresses has a different decimal precision than others, only one option is valid:

    • Parse amountOfTokensPerPacket using each token’s specific decimal precision (wei values). Funding packet amounts must then be specified in whole units at the API level for purchase(), etc. As stated above, such a funding packet cannot be used in campaigns featuring Discount or Interest mechanisms. ----------------------------------------------------------------------------------------------------------------------------_

Parameters

NameTypeDescription
lstruct FundingErc20PacketsFacetStorage.LayoutA reference to the Layout struct in storage.
postFractionFundingPacketDatabytesThe ABI-encoded data containing the following: - tokenAddresses: An address array containing the addresses of the ERC20 tokens encapsulated by the input packet. - amountOfTokensPerPacket: A uint256 array specifying the amount for each corresponding token in tokenAddresses.

Return Values

NameTypeDescription
[0]uint256uint256 The ID of the campaign for which the funding packet is configured.
[1]address[]address[] The tokenAddresses array.
[2]uint256[]uint256[] The amountOfTokensPerPacket array.

transferFundingPackets

function transferFundingPackets(struct FundingErc20PacketsFacetStorage.Layout l, uint256 campaignId, address from, address to, uint256 amountOfPackets) internal

Transfers the specified amount of a given campaign's funding packets from the from address to the to address.

The amounts to be transferred are calculated as: amountOfTokensPerPacket[i] * amountOfPackets for each token in the funding packet, where i is the index of the token in the tokenAddresses array. The transfer is performed using the safeTransferFrom method of the ERC20 token interface.

Parameters

NameTypeDescription
lstruct FundingErc20PacketsFacetStorage.LayoutA reference to the Layout struct in storage.
campaignIduint256The unique identifier of the targeted campaign.
fromaddressThe address from which the ERC20 assets encapsulated by the specified number of funding packets to be transferred.
toaddressThe address to receive the ERC20 assets encapsulated by the specified number of funding packets.
amountOfPacketsuint256The number of funding packets to account for.

addAcceptedFundingToken

function addAcceptedFundingToken(struct FundingErc20PacketsFacetStorage.Layout l, address tokenAddress) internal

removeAcceptedFundingToken

function removeAcceptedFundingToken(struct FundingErc20PacketsFacetStorage.Layout l, address tokenAddress) internal