drips-network / app

💧 Funding that flows — Drips Frontend
https://drips.network
GNU General Public License v3.0
31 stars 17 forks source link

Address for accepting donations to a Project or Drip List #824

Open brandonhaslegs opened 10 months ago

brandonhaslegs commented 10 months ago

Discussion is here

Essentially the idea is generating an address that users can send tokens to which automatically sends to the Drip List or Project. The benefit of having this is users don't have to make an account (connect a wallet, find the project/list, top up funds, etc) to participate in Drips.

efstajas commented 10 months ago

Quick rundown of the technical idea as I understand it…

We'd need:

1) a proxy contract that allows the owner of a particular drips account ID to access all ERC-20 funds it holds, and call Drips functions on its Address Driver account ID. Ideally, somehow anyone could call the functions required for pushing funds from the contract's balances to the respective Drip List or Project's splittable balance, so that funds donated to the proxy contract aren't stuck until the owner comes along to collect them. @CodeSandwich can we do that? 🤔 2) a factory that can deploy those proxy contracts at a deterministic address derived from the respective Drips account ID it's being deployed for

With this in place, we can add to the app:

CodeSandwich commented 10 months ago

a proxy contract that allows the owner of a particular drips account ID to access all ERC-20 funds it holds, and call Drips functions on its Address Driver account ID.

I think that the "access all ERC-20" and "call Drips functions" is not possible in a generic solution, because there's no clear definition of the "account ownership" in Drips outside of each driver code. What we can do in a generic way, is to only allow giveing to the account ID for which the proxy contract has been created.

The proxy contract derived from accountId will only expose a single function: function give(erc20). It will query erc20 for the amt it holds, and then it will call AddressDriver.give(accountId, erc20, amt), that's it. This approach is simple, generic and permissionless, there's no harm in strangers calling give. There's also no account ID ownership resolution, because there are no functionalities that would require any authorization.

The downside is that in order to track down who exactly made the donation, we'll need to check if the address that called AddressDriver.give(...) is a proxy (easy if we use a factory to deploy the proxies), and if it is, scan the Transferred events for the ERC-20 we're interested in.

A call that deploys such a proxy contract whenever a new Drip List is created or Project claimed

It could be easier to do the deployment on the first usage, because it won't add an extra step in the project claiming or list creation flow. The deployment on the first usage must be implemented anyway, because of point 3, a way to retroactively deploy.

efstajas commented 10 months ago

The downside is that in order to track down who exactly made the donation, we'll need to check if the address that called AddressDriver.give(...) is a proxy (easy if we use a factory to deploy the proxies), and if it is, scan the Transferred events for the ERC-20 we're interested in.

Hm, I haven't thought about that. I suppose in order to display balances for these proxy contracts we're going to need to make use of some ERC-20 balances API. Our backend obviously can't track all transfer events emitted by all ERC-20 contracts…

It could be easier to do the deployment on the first usage, because it won't add an extra step in the project claiming or list creation flow.

Just to be clear, I understood that the goal is that each individual Drip List and Project gets its own separate proxy contract and thus donation address, right? So we could just batch the contract creation in with the existing batches for claiming a project and creating a Drip List.

CodeSandwich commented 10 months ago

the goal is that each individual Drip List and Project gets its own separate proxy contract and thus donation address, right?

Yes, but we don't need to deploy anything until we want to call give(erc20). We can calculate the deterministic proxy address off-chain, display it in the app, and ask people to send funds there. If somebody looks up the address, they will see an address with no code, as if it was an EOA, a perfectly valid recipient of ERC-20 and plain ETH. Only when somebody wants to call give for the fist time, we need to deploy the contract. It will get the same address as we calculated off-chain, and at the moment of the deployment it will already hold all the assets, including plain ETH.

CodeSandwich commented 10 months ago

Our backend obviously can't track all transfer events emitted by all ERC-20 contracts…

It does sound big, but it depends a lot on the way we're getting the events in the backend. If we're querying Infura for the events coming from a specific contract, then we clearly can't cover everything, maybe a handful of known tokens. But if we somehow gain access to the stream of all events, e.g. by running a client ourselves or using some special Infura API, maybe we could aggregate all the Transferred events, and then filter them for any recipient address we want. With the backend it doesn't need to be impossible anymore.