Configuring PlatformGeneric FacetsState Facet

State Machine

The status of any campaign is managed by a state machine represented by the generic StateFacetStorage and internal and subinternal state facets, which collectively dictatate the transitions between states.

Each time a state-modifying function is called, the campaign state gets updated in the StateFacetStorage. For instance, calling createFractions() after launching a campaign updates the state of the campaign within the StateFacetStorage.

States do not directly determine which functions users can call during a running campaign. Instead, this behavior is enforced by the logic within the Internal and SubInternal State Facets associated with each state, which define function accessibility throughout the campaign’s lifecycle.

Note

Every fraction platform is required to include generic StateFacet in the diamond proxy.

image

States Transition

State-modifying functions call the changeState() function on the StateFacet. Consider the _updateState() function specified in the Erc1155WithGenesisFractionFacetStorage, that updates the state of the campaign in the StateFacetStorage:

function _updateState(address fractionAddress, uint256 upperGenesisId) internal returns (uint256 campaignId) {
    GeneralStorage.Layout storage generalStorage = GeneralStorage.layout();
    campaignId = ++generalStorage.currentId;
 
    generalStorage.infoForId[campaignId].fractionsContract = fractionAddress;
    PurchaseSkeletonGenesisIdsStorage.layout().infoForId[campaignId].upperGenesisId = upperGenesisId;
 
    // We progress from state 0 (NON_EXISTENT) to state 1 (CREATED) for this ID
    uint256 currentState = IStateFacet(address(this)).getStateOfId(campaignId);
    if (currentState != 0) revert CampaignAlreadyCreated(campaignId);
 
    IStateFacet(address(this)).changeState(campaignId, currentState, CAMPAIGN_CREATED_STATE);
}

Note how the function interacts with StateFacet through the IStateFacet interface to make the changeState() call. See the changeState function of the StateFacet below:

function changeState(uint256 campaignId, uint256 fromState, uint256 toState) external onlyInternalDelegateCall {
    StateFacetStorage.layout().changeState(campaignId, fromState, toState);
 
    emit StateChanged(campaignId, fromState, toState);
}

As shown in the changeState() function signature, the state always transitions from fromState which must reflect the current state of the campaign - to the new state specified by the toState argument. Both states are represented as uint256 values.

To set up the possible state options for the campaigns and its allowed state transitions, you have to initialize StateFacetStorage.

On this page