Secondaries Fees Implementation Design ===== REQ: *"When an NFT is resold within the platform, the original owner and sponsor receive 5% in fees eternally on every sell of said asset"* <style>.markdown-body { max-width: 1500px; }</style> ```solidity struct Asset { AssetState state; bytes32 subdomain; Token token; address owner; Fee sponsor; //new props address originalOwner; address originalSponsor; } ``` Sequence diagram ---- ```mermaid sequenceDiagram title: Asset Listing #------- actor MarketplaceOwner actor AssetProvider actor Sponsor actor Scheduler #------- participant MKPContract participant AssetManagerContract participant ListingManagerContract participant ISaleStrategy MarketplaceOwner->>MKPContract: enable secondary fee MarketplaceOwner->>MKPContract: set secondary fee % note left of MKPContract: guessing it is not set by asset instead AssetProvider->>AssetManagerContract: register Asset note right of AssetProvider: ... at some point in the future alt original owner not set AssetManagerContract--)AssetManagerContract: set originalOwner on asset end Sponsor->>AssetManagerContract: validate sponsorship note right of Sponsor: ... at some point in the future alt validation is possitive and secondary fees enabled and original sponsor not set AssetManagerContract--)AssetManagerContract: set originalSponsor on asset end AssetProvider->>ListingManagerContract: create listing note right of AssetProvider: ... at some point in the future alt secondary fees enabled and originalOwner != asset.owner ListingManagerContract--)ListingManagerContract: add original owner fee to the fees list end alt secondary fees enabled and originalSponsor != asset.sponsor ListingManagerContract--)ListingManagerContract: add original owner fee to the fees list end ListingManagerContract->> ISaleStrategy: end auction(listingId, assetId, fees) note right of ListingManagerContract: ... at some point in the future ISaleStrategy->> ISaleStrategy: calculate fees ISaleStrategy->> ISaleStrategy: _collectAuctionFees ISaleStrategy->> ListingManagerContract: distributeFees() ``` 1. if the secondary fees setting was enabled and the fees set on createListing, and then the feature is disabled before that auction ends, that auction will still keep the fees and they will be distribute at the end. the feature being disabled will only apply to new listing. the same should happen the other way round. 2. the first time the the asset gets listed the secondary fees are not set on the listing. 3. once the sponsorship has been validated the first time for the asset, it will remain as the originalSponsor FOREVER