Closed 0x4007 closed 11 months ago
/start
Deadline | Thu, 02 Nov 2023 14:49:16 UTC |
Registered Wallet | 0xAe5D1F192013db889b1e2115A370aB133f359765 |
/wallet 0x0000...0000
if you want to update your registered payment wallet address @user.So the original issue sounds like "we should allow bounty hunters with 0 XDAI to claim rewards" for a better UX.
There are 4 options:
Option 1: Meta TXs
We're generating permits using the uniswap's permit2 contracts. The thing with permit2 is that rewards can be claimed only by msg.sender
for the following reasons. So when a claim transaction is relayed by some 3rd party service (ex: Gelato Network) the msg.sender
equals to the relayer address which will revert because msg.sender
must be equal to a bounty hunter's address.
Option 2: Account abstraction (EIP-4337)
I haven't checked in depth but this is how it works as far as I understand:
UserOperation
in terms of EIP-4337)executeOp()
method).Here is the same situation as with relayers. On-chain transaction is initiated by the bundler so msg.sender
will be equal to the bundler's address so as far as I understand we can't use permit2 with any account abstraction SDKs (but I'm not 100% sure, need to check it).
Perhaps we could sign permits for smart contract wallets. Smart contract wallet addresses are deterministic (i.e. can be precomputed because of CREATE2
usage) but even if permit2 works with smart contract wallets it adds a certain overhead on the bot's side. Overall this requires a research.
Option 3: Redirect to a ready to use XDAI faucet
There is a ready to use XDAI faucet so we could simply redirect bounty hunters there.
Option 4: Our own server-side solution that transfers XDAI on demand
We could deploy our our backend service (supabase edge function or cloudflare worker) that would transfer XDAI on demand.
How it would work:
pay.ubq.fi
pay.ubq.fi/api/faucet?address=0x01
)0x01
is registered in the bot's DB and the address has 0 XDAI then a transaction is sent with some XDAI to a bounty hunter's addressTXs gas costs:
Given this with 1 USD we can onboard ~2000 new users. Even if the service is abused we would lose only 1 USD.
To sum up
I think the best strategy is to fulfill a research on account abstraction (whether we can use smart contract wallets for permit2). If we can't use account abstraction then we should implement redirect to XDAI faucet (because it's simple and fast) and then implement our own backend faucet solution.
Appreciated rndquu
I was just trialling out using OpenZeppelin's Defender.
As for introducing a fee I was having a hard time with without adding multiple tx steps but as you said with $1 == 2000 users, its not like it's breaking the bank
I'm not uncertain that this or near enough is doable but won't know for sure til POC
Also, the claim portal will this be the only one across all instances of claiming? No partner white-labelled portals or own brand ones? Or is this ubiquity specific?
What I'm getting at is if we setup one relay for gnosis to handle this, will it be responsible for all instances of hunters claiming from partner issues too? Or will each partner have to set things up like this too?
Also, the claim portal will this be the only one across all instances of claiming? No partner white-labelled portals or own brand ones? Or is this ubiquity specific?
As far as I understand pay.ubq.fi
will be a single reward UI for all of our partners.
What I'm getting at is if we setup one relay for gnosis to handle this, will it be responsible for all instances of hunters claiming from partner issues too? Or will each partner have to set things up like this too?
We should make partner UX as simple as possible. So if relaying a transaction requires calling a single API method then it is simpler to be responsible for relaying all partner transactions unless we're subjected to some fees or API rate limits.
Yes we should handle this across every partner. Again, if we deduct from the assignee's payout, then it is technically profitable to run this service.
We are incentivized to run this service for everybody for 1. better user experience and 2. small profit
Okay well I'm thinking that we do it like this:
Thoughts on that?
Something like this is probably easiest, as we already have pk access we can handle transfers direct to the user from the bot, can't we? or is there risk to this that I'm not seeing?
Okay well I'm thinking that we do it like this:
- Just before the permit is generated we balance check the user, if they have enough gas we don't debit.
- If they have 0 gas we debit 1xDai from the reward and transfer 0.5 to the user before they even get to the claim page
- The bot leaves a comment (or is included in the permit comment) something like "As you had no gas to claim, we have debited your award by 1 xDai to allow you to claim, as a deterrent from abuse there is a 0.5 xDai service fee."
Thoughts on that?
Something like this is probably easiest, as we already have pk access we can handle transfers direct to the user from the bot, can't we? or is there risk to this that I'm not seeing?
Debiting the reward is complex. I guess we can simply transfer 0.0003 XDAI
to a bounty hunter on permit generation if:
And add some bot comment like "We've funded your wallet address with 0.0003 XDAI (tx url) for you to claim a reward. Thank you for your 1st contribution". So by the time bounty hunters opens a claim URL page the tx should already be mined (keeping in mind gnosis's 5 sec block time).
Just to be clear when I say debit I really meant just reduce their payout by $1 before permit generation, not adding debits to the db.
Glad you see it similarly, this is super onboarding friendly but there's no opt in or out and no way to make it profitable but if making it profitable is a key point then it could be opted into during the pr stage? They could register with the bot something like /subsidise and it'll opt them in for a $1 payout reduction receiving .5 of that while we keep the service fee?
Maybe there is a cleaner way to opt in?
For me both approaches (a separate /subsidise
command or automatically deducting 1$ from a reward for gas fees on 1st permit generation) are fine.
One more point is that it is not clear how to collect a service fee. I mean that payout rewards are signed by partner accounts while a service fee should be somehow collected by ubiquity's faucet account. So we somehow need to transfer a service fee from a partner's account to ubiquity account.
P.S. It seems that the current issue should be moved to the https://github.com/ubiquity/ubiquibot repo.
So a partner signs for the payout but the $0.5 comes from the UBQ account.
I guess we can simply transfer 0.0003 XDAI
I'm assuming that you meant from the UBQ account when you said this ^ and not the partner account
The $1 coming from UBQ means we could generate a $1 permit from the partner to UBQ and then claim it straight to the UBQ account, no?
So we just deduct $1 from the payout amount, generate a permit for say $11.50 for the user and $1 for UBQ upon completion, we have the bot claim that permit and then send the $0.5 to the user?
Factoring in confirmation time I'm unsure what the best thing to do would be as:
P.S I may be misunderstanding the way things work under the hood but as far as I know, the bot has access to both UBQ and Partner accounts when running, so we can send funds directly to the user from UBQ as well as have the permission to generate a permit for UBQ to actually claim from the partner wallet?
I'm assuming that you meant from the UBQ account when you said this ^ and not the partner account
Yes
The $1 coming from UBQ means we could generate a $1 permit from the partner to UBQ and then claim it straight to the UBQ account, no?
Yes, we could
So we just deduct $1 from the payout amount, generate a permit for say $11.50 for the user and $1 for UBQ upon completion, we have the bot claim that permit and then send the $0.5 to the user?
Yes, it could work this way
Factoring in confirmation time I'm unsure what the best thing to do would be as:
- Partner has no funds, the permits are still generated, the $1 would fail and we'd still send the .5.
- Or, if they have no funds we don't send it but then it becomes well how do we facilitate it then, would it be a function of the bot on the pr or issue or a function of the claim portal or would we log the failed $1 claims to the db and they can be manually or semi-manually claimed
Yes, it seems that we should save failed 1$ "faucet" claims to a DB and try to claim later.
P.S I may be misunderstanding the way things work under the hood but as far as I know, the bot has access to both UBQ and Partner accounts when running, so we can send funds directly to the user from UBQ as well as have the permission to generate a permit for UBQ to actually claim from the partner wallet?
Yes, the bot has access to partner accounts (i.e. their wallet private keys). The "UBQ account" you're referring to can be considered as a separate partner (i.e. the whole ubuiquity organization is a separate partner with its own wallet private key regardless that it also maintains the bot). So I think that there should be a separate "ubiquity faucet account" for 1$ faucet transfers.
have the permission to generate a permit for UBQ to actually claim from the partner wallet
Yes, we have this option but this looks fishy from a partner's view. I mean that some 3rd party organization generates permits and transfers funds from partner's wallet. But I can't think of a better approach.
Awesome, well I mean, I can see how that might come across fishy but it's not like that inherent risk wasn't there to begin with, it's just that we are now trying to leverage it for our gain so it does start to stink a lil I guess.
I've been pondering the idea of them somehow restricting us to permits of at max $1 that would supersede any actual permit amount but I do not think that functionality exists.
The only other way that I can think of is custom smart contract or safe module but that would grow arms and legs as a bounty and add additional setup for new partners, although it could be done
It might be simplest to start a new codebase/service dedicated to just being a pay.ubq.fi faucet (we can probably fork one.)
We can top it up with some money and pay.ubq.fi can handle the logic of automatically claiming a faucet top-up based on what was discussed above.
This approach is insecure but it is possible that abuse is not an issue for a long, long time.
I also am starting to think more on if we should offer two modes of the bot in the future:
Ideally we can figure out all the UI/UX to give users a "centralized mode" experience, but with a genuine decentralized backend to stay true to DeFi values.
This may require that users no longer directly register their EOAs, but instead we generate some hosted/smart contract wallet for them. Then we can run transactions on their behalf.
It might be simplest to start a new codebase/service dedicated to just being a pay.ubq.fi faucet (we can probably fork one.)
As far as I understand you're proposing a dedicated backend service (i.e. cloudflare worker) which will expose a single API like /faucet?address=0x01
for topping up a specified bounty hunter's address if:
So when a bounty hunter opens pay.ubq.fi
to claim a reward then:
pay.ubq.fi/faucet?address=0x01
to top-up the balanceCorrect?
If the profit-from aspect is removed the simplest way would be to transfer 0.0003 direct to the hunter on pr merge, we use github api to search for merged prs into ubiquity if none then deal if 1 then no deal. It's just a secure as the rest of the bot, and cannot be abused without actually contributing to the project, so ultimately it cannot be abused.
We could write a simple smart contract with a user mapping that allows one subsidy per user, only callable by the bot filled with a couple xDai, we check the mapping on merge if true no subsidy, if false we call it. We could also add WXDAI to xDAI conversion and vice versa (subject to slippage etc ofc).
Didn't see your comment @rndquu, that makes more sense and a better iteration of what I had in mind
I don't yet understand fully how the debit cards will work, excited to see them rolled out though for sure but I'd have thought the cards would be built in as standard either way but yeah it does appease both sides of the fence offering both doesn't it.
As for the centralized mode I think it's what non-natives and web2 folks might opt for and could be approached with AA and Safe, we build safe modules that handle everything at contract level things like fees for centralized usage option either to a profit or to make it a self-sustaining eco-system where fees paid in are used to subsidise tx's etc so at a user level everything just works 'for free' (minus service charge) and they need only sign in with a username & password. Or with 1 signer access to each safe and we can freely debit accounts after rewards are paid in.
A lot of scope for it, I remember a wallet which already exists that allows us to store the PK for repeat transactions but I cannot for the life of me remember it right now.
As far as I understand you're proposing a dedicated backend service (i.e. cloudflare worker) which will expose a single API like
/faucet?address=0x01
for topping up a specified bounty hunter's address if:
- bounty hunter's wallet is registered in the bot's DB
- this is the 1st issue solved by a bounty hunter
- bounty hunter's wallet has 0 XDAI
So when a bounty hunter opens
pay.ubq.fi
to claim a reward then:
- Frontend calls smth like
pay.ubq.fi/faucet?address=0x01
to top-up the balance- We show an info msg like "Your address is being prefunded, pls wait for this transaction to be mined"
Correct?
This sounds like an excellent approach.
I wish there was a way to make the top-up more seamless. I'm unsure about the 5 seconds being fast enough for it to be seamless for new users.
I was thinking it would be nice to prefund the wallet as soon as the permit is generated. That way, when the contributor goes to claim, they should already have the xDAI.
Perhaps the bot can call the "invoke faucet" API endpoint when generating payment permits instead of pay.ubq.fi UI?
Then one day in the future, we can iterate and figure out how to subtract it from their permit (although I feel that this will require some type of SAFE/account abstraction solution.)
Perhaps the bot can call the "invoke faucet" API endpoint when generating payment permits instead of pay.ubq.fi UI?
That's exactly what @Keyrxng proposed.
To sum up, as a part of this issue we should implement a server side app (in a cloudflare worker) which exposes a single API endpoint similar to /?faucet?address=0x01
which accepts an address to fund.
The faucet service should have access to the bot's DB in order to fund only when:
We'll use this faucet service in the bot on permit generation.
@Keyrxng Sounds good?
It sounds exactly like transfer user .00003 xDai from the bot on permit generation but with extra steps
that to me don't serve any really benefit as opposed to just sending directly from the bot, other than it adding another point of failure imo. A lot of additional work for something that would be 20 or so lines of codes for the bot with better error handling in cases when cloudflare fails.
So create a worker that has PK access to an EOA, and call that API on permit generation from the bot so that the EOA sends 0.0003 gas to the user as soon as permit is generated so long as the requirements are met.
The worker will be standalone, will require db access, pk access, and manually be funded with xDai by UBQ?
Am I understanding this right?
It sounds exactly like transfer user .00003 xDai from the bot on permit generation but with extra steps that to me don't serve any really benefit as opposed to just sending directly from the bot, other than it adding another point of failure imo. A lot of additional work for something that would be 20 or so lines of codes for the bot with better error handling in cases when cloudflare fails.
I guess the idea is to have a generalized solution which could be used in the bot or in pay.ubq.fi
or somewhere else like our own facet website should we have such an idea.
The worker will be standalone, will require db access, pk access, and manually be funded with xDai by UBQ?
Yes
It sounds exactly like transfer user .00003 xDai from the bot on permit generation but with extra steps that to me don't serve any really benefit as opposed to just sending directly from the bot, other than it adding another point of failure imo. A lot of additional work for something that would be 20 or so lines of codes for the bot with better error handling in cases when cloudflare fails.
I guess the idea is to have a generalized solution which could be used in the bot or in
pay.ubq.fi
or somewhere else like our own facet website should we have such an idea.The worker will be standalone, will require db access, pk access, and manually be funded with xDai by UBQ?
Yes
P.S. A agree that initiating a transfer from the bot's code is simpler but our requirements are changed frequently so generalized solutions seems to be better.
When you put it like that it does make more sense, I'm too narrow minded 😂
@Keyrxng - Releasing the bounty back to dev pool because the allocated duration already ended! Last activity time: Thu Nov 09 2023 10:18:10 GMT+0000 (Coordinated Universal Time)
@Keyrxng The time limit for this bounty is on Sat, 18 Nov 2023 14:35:43 UTC
@Keyrxng - Releasing the bounty back to dev pool because the allocated duration already ended! Last activity time: Thu Nov 09 2023 10:18:10 GMT+0000 (Coordinated Universal Time)
@Keyrxng Could you self assign again?
/start
Deadline | Sat, 18 Nov 2023 17:44:44 UTC |
Registered Wallet | 0xAe5D1F192013db889b1e2115A370aB133f359765 |
/wallet 0x0000...0000
if you want to update your registered payment wallet address @user.0xAe5D1F19...33f359765
That's exactly what @Keyrxng proposed.
To sum up, as a part of this issue we should implement a server side app (in a cloudflare worker) which exposes a single API endpoint similar to
/?faucet?address=0x01
which accepts an address to fund.The faucet service should have access to the bot's DB in order to fund only when:
We'll use this faucet service in the bot on permit generation.
Original Specification Context
Overview
To onboard normal developers who aren't crypto native, perhaps we can consider virtual wallets, in browser wallets, or for the most simple starting point: automatically transfer the funds if they don't have any gas.
Scenario
Faucet Limitations