ubiquity / ubiquibot

Putting the 'A' in 'DAO'
https://github.com/marketplace/ubiquibot
MIT License
16 stars 59 forks source link

Taiko #883

Open 0x4007 opened 7 months ago

0x4007 commented 7 months ago

Overview

We will automate the generation of the POAP properties using all of the relevant GitHub metadata of the closed issue, including but not limited to: the organization name (Taiko) repository name, issue number, and their contribution style. This can allow for advanced filtering and analytics around the POAPs that are generated.

We will modify this contract https://github.com/Uniswap/permit2/blob/erc721/src/ERC721/SignatureTransferERC721.sol and add a new permitMint() method. This will allow users to mint the POAP only if they contributed to the closed issue. Given the bot's current capabilities this means that they were either a commenter of the issue/associated pull request, the author of the issue, or the assignee of the issue.

Timeline

Month 2 (8,013 Taiko tokens awarded): (Prototype)

Month 4 (8,013 Taiko tokens awarded): (Beta)

Month 6 (8,013 Taiko tokens awarded) (Release)

0x4007 commented 7 months ago

@rndquu I think we can break things off and work concurrently on these objectives.

Perhaps you can handle the fork of the permit contract. Do you think it's possible for you to produce a mock interface so that @wannacfuture can work on the UI?

Lastly I think @whilefoo should work on the config given that they just finished redoing all of the bot config last week.

The specification is a copy/paste of the proposal I sent to Taiko, however I think we can realistically finish everything within a month if we are productive.

@sergfeldman I assume you have extra bandwidth to stay on top of this from a project management perspective?

rndquu commented 7 months ago

To clear things out. Some projects (like Taiko) don't have cash rewards. They simply mint a POAP (i.e. ERC721 NFT) with contributions of a particular bounty hunter. Basically we should allow bounty hunter payouts in NFT (in addition to our existing permit2 cash rewards).

So the bot will be able to generate permits for 2 cases:

  1. permit2 cash rewards (which we're using right now)
  2. permit2 NFT rewards (no cash rewards, simple NFT minting)

For a bounty hunter the flow is going to be this one:

  1. Bounty hunter solves an issue
  2. The bot generates a "permit NFT URL" (which is basically ERC721 mint inside)
  3. Bounty hunter opens the "permit NFT URL"
  4. Bounty hunter clicks the "Claim POAP" button
  5. Bounty hunter mints a new ERC721 reward token with contribution details inside (organization name, repository name, issue number, contribution type (assignee, issue creator, commenter, etc...))

Perhaps you can handle the fork of the permit contract.

Yes, I'll create a new contract forked from https://github.com/Uniswap/permit2/blob/erc721/src/ERC721/SignatureTransferERC721.sol with a new permitMint() method

Do you think it's possible for you to produce a mock interface so that @wannacfuture can work on the UI?

Right now I can't say for sure what the contract interface will look like. @wannacfuture You could create a separate branch at https://github.com/ubiquity/pay.ubq.fi/ with the "Claim POAP" button. We can check the reward token address from the permit json. So if it is ERC20 then show our standard permit2 layout, if reward token is ERC721 then show the "Claim POAP" button. Then (when the SignatureTransferERC721 contract is ready) we could make it ready for production.

Lastly I think @whilefoo should work on the config given that they just finished redoing all of the bot config last week.

Regarding the bot's config, right now the rewards tokens are hardcoded. Moving the token reward address to a separate config param seems to be not the best decision because our own "ERC721 NFT rewards contract" will be very specific so I hardly image that some partner would need to rewrite the contract's address. We could add a new bot config param like reward-type = ERC20 | ERC721 to distinguish ERC20 rewards from POAP (i.e. NFT) rewards.

0x4007 commented 7 months ago

I feel that if we are already building the capability, we should allow both cash and NFT rewards concurrently because the additional effort required I expect to be marginal. If for some reason it is a tremendous effort to enable both simultaneously then I'm okay to add that capability later.

sergfeldman commented 7 months ago

@sergfeldman I assume you have extra bandwidth to stay on top of this from a project management perspective?

I hope that the next several weeks will be busy with intensive negotiations on the card issuing. Not sure that I can actively engage in project management of this project, but I can try if needed.

gitcoindev commented 7 months ago

I feel this is related to multi-token permits:

https://github.com/ubiquity/pay.ubq.fi/issues/136 https://github.com/ubiquity/ubiquibot/issues/769

and permits table schema https://github.com/ubiquity/ubiquibot/issues/811

the NFT / ERC721 token mint + multiple ERC20 token payouts could be combined into an array of permits and pay.ubq.fi could enable redeems for each payout / mint.

wannacfuture commented 7 months ago

Right now I can't say for sure what the contract interface will look like. @wannacfuture You could create a separate branch at https://github.com/ubiquity/pay.ubq.fi/ with the "Claim POAP" button. We can check the reward token address from the permit json. So if it is ERC20 then show our standard permit2 layout, if reward token is ERC721 then show the "Claim POAP" button. Then (when the SignatureTransferERC721 contract is ready) we could make it ready for production.

Got it. Let me take a look what I can do for the refined UI.

rndquu commented 7 months ago

Right now I can't say for sure what the contract interface will look like. @wannacfuture You could create a separate branch at https://github.com/ubiquity/pay.ubq.fi/ with the "Claim POAP" button. We can check the reward token address from the permit json. So if it is ERC20 then show our standard permit2 layout, if reward token is ERC721 then show the "Claim POAP" button. Then (when the SignatureTransferERC721 contract is ready) we could make it ready for production.

Got it. Let me take a look what I can do for the refined UI.

A new requirement is that pay.ubq.fi should be able to accept an array of permits. For example, bounty hunter (issue solver) could get 3 rewards simultaneously:

So if pay.ubq.fi gets an array of permits then:

0x4007 commented 7 months ago

I'm mobile now and it isn't convenient for me to check the issues but I vaguely recall we had a design for saving all the owed payments in the database and then generating a single claim permit to "roll up" the transactions.

Was this backlogged or can we go for this in conjunction with passing in an array (to claim different tokens, as I presume a single permit can not transfer multiple token types)

Keyrxng commented 7 months ago

as I presume a single permit can not transfer multiple token types

You can transfer multiple ERC20 tokens but not any other types via one permit but it'll have a heavier claim fee so the faucet would need to be adjusted to calculate the fee dynamically as opposed to the hardcoded env var.

function permitTransferFrom(
        PermitBatchTransferFrom memory permit,
        SignatureTransferDetails[] calldata transferDetails,
        address owner,
        bytes calldata signature
    ) external {
        _permitTransferFrom(permit, transferDetails, owner, permit.hash(), signature);
    }

Some projects (like Taiko) don't have cash rewards.

In such a case where the project isn't a cash based reward system, are we perpetually covering the claim fees for those partners if applicable?

0x4007 commented 7 months ago

You can transfer multiple ERC20 tokens

Cool

In such a case where the project isn't a cash based reward system, are we perpetually covering the claim fees for those partners if applicable?

Good question. Knee jerk reaction would be to have partners cover their own faucets but if this is complex to set up then it makes the most sense for us to host it.

rndquu commented 7 months ago

I'm mobile now and it isn't convenient for me to check the issues but I vaguely recall we had a design for saving all the owed payments in the database and then generating a single claim permit to "roll up" the transactions.

Yes, but those owed payments are grouped by reward token address. So each reward token tallies up its own reward debt per bounty hunter. Hence when a single permit URL is generated we planned to pass an array of permits to pay.ubq.fi.

Was this backlogged or can we go for this in conjunction with passing in an array (to claim different tokens, as I presume a single permit can not transfer multiple token types)

Yes, it was backlogged https://github.com/ubiquity/pay.ubq.fi/issues/136

You can transfer multiple ERC20 tokens but not any other types via one permit

Yes, we can transfer multiple tokens in a single permit but only those tokens which support ERC20 interface. It's not applicable to Taiko's POAP. Anyway I would keep it simple for now and let pay.ubq.fi accept an array of permits which could be claimed one by one. And later, in the next dev iteration, update the bot to generate combined ERC20 permits (combined so that all ERC20 rewards could be processed in a single transaction).

0x4007 commented 7 months ago

@rndquu when can you get started?

rndquu commented 7 months ago

@rndquu when can you get started?

I'm starting this week

whilefoo commented 7 months ago

This is a first iteration of the config

paymentTokens:
  - evmNetworkId: 1
    tokenType: ERC20 | ERC721
    tokenAddress: 0x...
    basePriceMultiplier: 1
    issueCreatorMultiplier: 1
    maxPermitPrice: 100

I'm guessing for ERC721 / NFT rewards the multiplier would be capped at 1. Will comment incentives be calculated differently depending on the token? If so, I'm not sure how it's gonna for work for NFT rewards because you can't really say for every word you get 0.1 NFT.

Will a user get multiple NFTs in one issue: 1 NFT for completing the bounty, 1 NFT for participating in discussion, 1 NFT for reviewing PR...? If so, is there any threshold for how much activity a user needs to generate? Like minimum X words or just any activity?

Maybe it'd be better to separate ERC20 / ERC721 rewards in the config:

tokenRewards:
  - evmNetworkId: 1
    tokenAddress: 0x...
    basePriceMultiplier: 1
    issueCreatorMultiplier: 1
    maxPermitPrice: 100
    incentives:
      comment:
        elements: ...
        totals:
           word: ...
           ...
nftRewards:
  - evmNetworkId: 1
    tokenAddress: 0x...
    incentives:
      issueSolver: true | false
      issueCreator: true | false
      issueCommenter: true | false
      reviewCommenter: true | false
0x4007 commented 7 months ago

Maybe it'd be better to separate ERC20 / ERC721 rewards in the config:

I think this probably makes sense. For whatever its worth, I anticipate projects to be generous with the NFT rewards as they do not have any monetary value. I think most partners would default to have them all enabled. We should make all enabled the first development milestone we hit as I think thats more valuable than the ability to disable specific types.

If so, is there any threshold for how much activity a user needs to generate? Like minimum X words or just any activity?

I think any activity is okay. The repository maintainers can delete/exclude their contributions before closing the issue if there is abuse.

Will a user get multiple NFTs in one issue: 1 NFT for completing the bounty, 1 NFT for participating in discussion, 1 NFT for reviewing PR...?

Yes I formalized the different ways to contribute into 17 unique "contribution classeses" during my refactoring. As such there conceivably could be up to 17 unique NFT types per issue, identified by their "contribution class."

There is a hierarchy so that you're consolidated into the single highest rank role in case you fit in multiple.

Contribution Class Overview

Issue View Commenters

Issue Issuer Comment
Issue Assignee Comment
Issue Collaborator Comment
Issue Contributor Comment

Pull Request Review Commenters

Review Issuer Comment
Review Assignee Comment
Review Collaborator Comment
Review Contributor Comment

Pull Request Review States

Review Issuer Approval
Review Issuer Rejection
Review Collaborator Approval
Review Collaborator Rejection

Code Contributors

Review Issuer Code
Review Assignee Code
Review Collaborator Code

Other

Issue Issuer Specification // special crediting just for writing the issue specification. 
Issue Assignee Task // who completed the task.

Appendix

Naming

The "class name schema" is as follows:

[ view ] [ role ] [ contribution ]

Views

  1. "Issue" on the actual issue view.
  2. "Review" on the pull request view.

Roles

  1. "Issuer" the author of the original issue.
  2. "Assignee" the issue assignee (can be multiple)
  3. "Collaborator" invited to the repository or organization as a collaborator.
  4. "Contributor" everyone else.
rndquu commented 7 months ago

Maybe it'd be better to separate ERC20 / ERC721 rewards in the config

Yes, separating the configs looks good. Initially we discussed (can't find the thread) that it should be enough to have a single new bot config param like use-nft-rewards: true | false and hardcoding all other values (like reward NFT contract address, what contribution types are eligible for NFT rewards, etc...) but if we have a development capacity for a separate NFT rewards config then of course it's much better.

0x4007 commented 7 months ago

I think it's responsible to aim for minimum viable product considering our timelines. We can iterate later if we are ahead of schedule.

whilefoo commented 7 months ago

Ok so then for the first iteration we will just add a param use-nft-rewards and make the bot generate generate an array of permits and modify pay.ubq.fi to handle it.

However I just want to make sure I understand how minting will work. I'm guessing this will be our own ERC721 token deployed on a chain (gnosis chain?) and also a modified version of permit2 that will have a permitMint function. It will have to accept signed metadata along with the address of the ERC721 token. I think the metadata will be quite small so we can store it directly on chain and not IPFS.

@rndquu let me know when you have the contract ready and in the mean time I'll prepare the bot

rndquu commented 7 months ago

@whilefoo

Ok so then for the first iteration we will just add a param use-nft-rewards and make the bot generate generate an array of permits and modify pay.ubq.fi to handle it.

+1

However I just want to make sure I understand how minting will work. I'm guessing this will be our own ERC721 token deployed on a chain (gnosis chain?) and also a modified version of permit2 that will have a permitMint function. It will have to accept signed metadata along with the address of the ERC721 token.

Basically it will be our own ERC721 token with lazy minting (i.e. the bot will be able to sign off-chain mint requests for particular bounty hunters so that they could mint NFTs using the bot's signature). This is yet a draft but it gives a glimpse of how lazy minting will work.

this will be our own ERC721 token deployed on a chain (gnosis chain?)

Yes, we'll start with gnosis

I think the metadata will be quite small so we can store it directly on chain and not IPFS.

Yes, since the initial deployment is on gnosis (with low tx fees) we're free to save everything on-chain

let me know when you have the contract ready and in the mean time I'll prepare the bot

ok

0x4007 commented 7 months ago

@rndquu we only have a few weeks for this first deadline. I was kind of expecting this to be done within the first couple of weeks. How is progress coming along?

rndquu commented 7 months ago

@rndquu we only have a few weeks for this first deadline. I was kind of expecting this to be done within the first couple of weeks. How is progress coming along?

The contract is 95% ready

rndquu commented 7 months ago

@whilefoo

NFT reward contract is ready, you may find all info at https://github.com/ubiquity/nft-rewards.

This is a js example of how to sign mint requests on the bot's side.

I've DMed you a private key from the minter's account (used in the deployed contract) which you should use for signing off-chain mint requests.