Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

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

"Virtual Rollups" via Transfer Hooks #656

Closed
sergfeldman opened this issue May 25, 2023 · 11 comments
Closed

"Virtual Rollups" via Transfer Hooks #656

sergfeldman opened this issue May 25, 2023 · 11 comments
Labels
Research Bounties that may include a report only, without code.

Comments

@sergfeldman
Copy link
Member

sergfeldman commented May 25, 2023

Basically the idea of being able to spend money on a Ubiquity debit card but deduct directly from a user's wallet balance. However, we can create a "virtual rollup" by deducting on the next transfer via a transfer hook. It might be cheaper to do a single debit to roll up all transactions vs every transaction debit in regards to gas fees.

ubiquity/research#2

@0x4007
Copy link
Member

0x4007 commented May 25, 2023

We need to create a research specification to have a transfer hook contract to be able to perform this behavior of rebasing a user's uAD balance before a transfer. It would be even more interesting if we had an off-chain oracle for the amount to be debited (so that it can change as many times as needed throughout the day - e.g. a user makes 20 debit card transactions)

Then the next time that the user wants to interact with their uAD with a transfer the transfer hook will rebase the user's balance from e.g. 1000 uAD to 850 uAD after the 20 debit card transactions from that day.

The purpose of the rollup is, of course, to save on gas fees by rolling up the user's many debits into a single on-chain transaction.

@0x4007 0x4007 changed the title Research around virtual rollups "Virtual Rollups" via Transfer Hooks May 25, 2023
@0x4007
Copy link
Member

0x4007 commented May 31, 2023

  • The off-chain oracle can be represented as "user delegated balance" where the amount begins with the amount of Ubiquity Dollars in the user's wallet, pre-transaction.
  • Next, a delegate service such as the Ubiquity Card modifies the "user delegated balance".
    • This is stored in an off-chain database, or on Gnosis Chain as the gas fees are negligible.
    • In this case, every time the Ubiquity Card is debited in the real world, it will subtract from the "user delegated balance."
      • as debitCard role, to enable access control management.
    • This architecture allows "on-chain Ubiquity Dollar balance" delegation for various off-chain contexts.
  • Finally, the pre-transfer-hook ensures that the user's balance is synchronized with the "user delegated balance"
    • This means that when the user transfers (this includes ANY movement of Ubiquity Dollars, including for redeeming collateral, or for swaps.) before the transfer begins, the user's balance is debited (burned) from.
    • For security reasons, it only makes sense to enable support for subtracting/debiting/burning Ubiquity Dollars from one's on-chain balance via this pre-transfer-hook.
      • This can be easily handled with our protocol access control manager by enabling only burn permissions on the "user delegated balance" transfer-hook contract address.

Final note, the Ubiquity Card service (off-chain) has a max spend limit of the user's current on-chain Ubiquity Dollar balance. Afterwards, it will read from the current balance provided by the "user delegated balance" oracle/API. Each debit on the debit card will subtract from the "user delegated balance."


What does the architecture look like to let the user activate a transfer hook via an approval call? I think it would be most comforting if users must deliberately opt in to enable delegated balances, otherwise there would be a lingering sense of insecurity for users that their money can be taken by the Ubiquity team or by hacks at any time.

@0x4007
Copy link
Member

0x4007 commented Jun 1, 2023

Request for comment @zgorizzo69 @rndquu

@0x4007 0x4007 added the Research Bounties that may include a report only, without code. label Jun 1, 2023
@rndquu
Copy link
Member

rndquu commented Jun 1, 2023

Sync gap

Traditional banks maintain a single source of truth (i.e. DB)

In the proposed architecture we should maintain 2 sources of truth:

  1. off-chain Ubiquity Card service (i.e. DB with user balances)
  2. on-chain UbiquityDollar contract with user balances

Maintaining 2 sources of truth we have a "sync" gap when user pays with his Ubiquity debit card.

Example (user balance 100 USD on-chain and off-chain):

  1. Time: 12:00:00. User pays 100 USD with his debit card (on-chain balance: 100 UAD, off-chain balance: 0 USD)
  2. Time: 12:00:00. User transfers 100 UAD to somebody (on-chain balance: 0 UAD, off-chain balance: 100 USD)

So on next trasfer code inside a transfer hook will fail to deduct 100 USD (which came in off-chain) because there is nothing to deduct

Flow

Consider an example with onchain confirmation (with successful result):

  1. User wants to buy a T-shirt in an online store for 10 UAD
  2. User enters his Ubiquity Card number
  3. User's card number is sent to the "Ubiquity Card Service" (which has allowance over user's balance)
  4. "Ubiquity Card Service" sends transfer transaction to gnosis chain that moves user's 10 UAD to the merchant (here we omit the "who pays for gas?" question because gas prices are really low in gnosis chain)
  5. "Ubiquity Card Service" waits 40 seconds for 8 block confirmations in gnosis
  6. "Ubiquity Card Service" sends a success webhook to the online store so that it could display a success message

Here on step 3 we should somehow distinguish a real card holder with an adversary who knows the card number. So we need an additional step of authentication (sms, push, OTP, etc...)

So basically we are sending a transaction on behalf of a user. I don't get why user should take additional risks by allowing some address his funds while he can simply use any wallet, sign transaction and send it without any 3rd party services.

@0x4007
Copy link
Member

0x4007 commented Jun 1, 2023

Traditional banks maintain a single source of truth (i.e. DB)

If the user wants to use the debit card feature (or any other off-chain extensions of the Ubiquity Dollar economy) the user is required to opt in to this "delegated balance service." Now this is the singular source of truth for the balance of that user. Once the user has enabled the "delegated balance service" on the next on-chain transfer of uAD, the balance will be rebased to what the "delegated balance service" thinks it should be.

If a user is not opted in, then they can not use any of these features with prevents any of these issues from happening in the first place. Meaning that by default, the single source of truth will be the user's on-chain balance as we would traditionally expect for any normal stablecoin project.

Time: 12:00:00. User pays 100 USD with his debit card
Time: 12:00:00. User transfers 100 UAD to somebody

I also think this is exceptionally difficult to get a transaction included and the block validated all in the same millisecond that the debit card payment was made and is checked by our server. Maybe possible so we should think about this more carefully.

Flow

  1. "Ubiquity Card Service" waits 40 seconds for 8 block confirmations in gnosis

I am not sure that the traditional finance system is compatible with this. I would imagine that the point-of-sale system would throw an error for such a long card transaction timeout. Also from the user's perspective: imagine going to a fast food restaurant and spending 40 seconds to buy a snack. I would not consider that as acceptable.

Here on step 3 we should somehow distinguish a real card holder with an adversary who knows the card number. So we need an additional step of authentication (sms, push, OTP, etc...)

I always like to default to Gnosis Safe because they support push notifications and transaction approvals on the iOS app, which is a very convenient form of on-chain two-factor authentication.

I don't get why user should take additional risks by allowing some address his funds while he can simply use any wallet, sign transaction and send it without any 3rd party services.

There is no way that we can offer a fully decentralized debit card. It must have a centralized component unfortunately due to laws and regulations. If you know of a way to hop on to traditional finance payment rails in a totally permission less way then we will absolutely do that. However as of now, there must be KYC for example, and the card must be authorized (accepted) by merchants in specific geographies following geographic specific regulations.

I'm unsure if I addressed all of your points fully.

Fiat Liquidity

There is one clarification I need to make in regards to liquidity in case it is not clear:

When we issue debit cards, I presume that we will need to have a fiat bank account with liquidity (e.g. $1M USD for all the early customers) and that balance must be topped up/managed daily in order to settle payments in the fiat world. So when a transaction happens with a merchant, it all happens on the fiat side.

However, because Ubiquity is providing that fiat liquidity, we must be made whole from our customer/user. The way we do this is by liquidating their on-chain uAD from their wallet so that they can't redeem collateral or spend it elsewhere on chain.

@rndquu
Copy link
Member

rndquu commented Jun 1, 2023

If the user wants to use the debit card feature (or any other off-chain extensions of the Ubiquity Dollar economy) the user is required to opt in to this "delegated balance service." Now this is the singular source of truth for the balance of that user.

So we should somehow block on chain transactions for that user while he is opted in to the "delegated balance service", right?

@0x4007
Copy link
Member

0x4007 commented Jun 1, 2023

I think it's easy to control transfer behavior on-chain including blocking with transfer hooks.

This question seems to be less around technology and more around strategy.

@rndquu
Copy link
Member

rndquu commented Jun 2, 2023

I think it's easy to control transfer behavior on-chain including blocking with transfer hooks.

This question seems to be less around technology and more around strategy.

I'm trying to understand how to prevent double spending from off chain and on chain user's balances.

So, from what I've understood so far, in case a user wants to opt in for the "delegated balance service" we should:

  1. Block user's on-chain transfers and operate only with an off-chain balance
  2. Sync off-chain balances with on-chain ones from time to time

@0x4007
Copy link
Member

0x4007 commented Jun 3, 2023

  1. Block user's on-chain transfers and operate only with an off-chain balance

Unfortunately this sounds exactly like depositing the tokens into a smart contract which defeats the vision of being able to keep your Ubiquity Dollars liquid in your wallet, while being able to spend them in the real world. Alternatively we could consider spend limits with the debit card and actually make their uAD balance negative (overdraft.)

Sybil attacks should be mitigated as debit cards presumably all require some form of KYC verification.

The overdraft idea is not ideal, but it will handle the edge case I replied to earlier with:

I also think this is exceptionally difficult to get a transaction included and the block validated all in the same millisecond that the debit card payment was made and is checked by our server. Maybe possible so we should think about this more carefully.

  1. Sync off-chain balances with on-chain ones from time to time

This will be synchronized in the pre-transfer-hook, every time transfer is invoked on the Ubiquity Dollar.

@rndquu
Copy link
Member

rndquu commented Jun 5, 2023

Alternatively we could consider spend limits with the debit card and actually make their uAD balance negative

This does not eliminate double spending but if there is a form of KYC on the "debit card side" then we could charge negative in such cases

@0x4007
Copy link
Member

0x4007 commented Jun 5, 2023

I also think this is exceptionally difficult to get a transaction included and the block validated all in the same millisecond that the debit card payment was made and is checked by our server. Maybe possible so we should think about this more carefully.

Another kernel of an idea that isn't completed but maybe could inspire something more fleshed out: what if we take inspiration from optimistic rollups, where we optimistically assume that everybody is a good actor, but if we detect any foul-play (attempted double spend) we can post the attestation and retroactively undo things on chain.

@ubiquity ubiquity locked and limited conversation to collaborators Jun 5, 2023
@0x4007 0x4007 converted this issue into discussion #671 Jun 5, 2023

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Labels
Research Bounties that may include a report only, without code.
Projects
None yet
Development

No branches or pull requests

3 participants