Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Represent invoices as ERC721 tokens #25

Merged
merged 11 commits into from
Oct 9, 2024
Merged

Conversation

gabrielstoica
Copy link
Collaborator

@gabrielstoica gabrielstoica commented Sep 18, 2024

Context

On-chain invoices are a strong narative. That's one of the problem Metadock is trying to solve. Having 100% transparency in the payee - payer relation can be an advantage and guarantee both from a freelancer and employer perspective.
Currently, all invoices have fields to represent important data such as start & end date, status, payment method, recurrence, asset used for the payment and amount. Apart from that, users can opt to create stream-based invoices implemented through the Sablier protocol.

To add an extra layer of flexibility, we're proposing to represent any invoice as an ERC-721 token. This feature gives the payee the ability to sell their invoices as they wish and benefit from instant liquidity. Other companies may want to buy invoices for financial purposes as well.

By having this representation, all invoices might have a unique set of attributes with custom values depending on the invoice scope. This unlocks new market paradigms in terms of how we trade invoices.

Implementation

By making the InvoiceModule.sol contract, an ERC-721 compliant collection, each time a new invoice is created, a new NFT will be minted to the initial recipient address. At the moment, the initial recipient can only be the user's instance of the Container.sol contract.

The ERC-721 transferFrom method has been overridden, allowing the current recipient of an invoice to transfer it to a different address. This method also transfers the Sablier stream NFT, only if the payment method is set to either linear or tranched stream (by checking the streamId value: non-zero means a stream is attached to the invoice). The transfer of the Sablier stream NFT is made by calling the withdrawMaxAndTransfer method implemented in the StreamManager.sol contract.

Caveats

An invoice payment can support 3 types of payments: transfer, linear or tranched stream. If linear or tranched stream selected, when the payment is made, a new Sablier stream is created. At this point, besides creating the stream itself, a new NFT will be minted to the recipient address.

Being minted through the SablierV2Lockup contract, this NFT can be independently transferred of the invoice one. In other words, if the Sablier stream NFT is transferred without also transferring the invoice NFT at the same time, the latest might become useless.

task: 1051e503bcd680c5a5ecc40ed84cf861

Copy link
Contributor

@V1d0r V1d0r left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to think about what comes first in the invoice and payment flow. Not only the known issue about the stream nft but also the case when invoices are partially paid or whatever reason. Should everything start with this invoice or should an invoice be generate at the end of the flow... Personally I feel an invoice should come first. Let's discuss.

@gabrielstoica
Copy link
Collaborator Author

We need to think about what comes first in the invoice and payment flow. Not only the known issue about the stream nft but also the case when invoices are partially paid or whatever reason. Should everything start with this invoice or should an invoice be generate at the end of the flow... Personally I feel an invoice should come first. Let's discuss.

@V1d0r As we've discussed in Teams, a new invoice must be created from the beginning so users can track key data (e.g. number of payments left, asset or amount) and manage on-chain ownership (e.g. invoice transfer). Therefore, a new NFT will be minted right after the invoice is created and, through the current implementation, it helps us to manage the invoice ownership: the owner of the NFT is also the owner of the invoice aka the payee.

On another note, the Sablier NFT will be minted only when the payer initiates the stream payment.

I'm going to merge this PR as it implements the required logic.

@gabrielstoica gabrielstoica merged commit 160116b into main Oct 9, 2024
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants