oceanprotocol / df-issues

Data Farming issue tracking
0 stars 0 forks source link

Q: How can OPF send OCEAN from multisig + HW wallets? (Web interface? Other?) #66

Closed trentmc closed 2 years ago

trentmc commented 2 years ago

Summary

Overall goal: Ensure that DF flow works where hardware wallets can fund OCEAN etc

Details

Here are the smart contract steps wrt paying rewards:

  1. OPF approves for DFRewards.sol to spend OCEAN. Call token.safeApprove(contract_addr, sum(values))
  2. OPF tells DFRewards.sol how much OCEAN each LP gets. Call DFRewards.allocate(tos, values, token_addr). Since there are thousands of LPs, it will batch this.
  3. Then, each LP claims

This issue is about step 1.

How does OPF do this approval (step 1)? OPF will be holding the funds in a multisig (gnosis safe) wallet, and signers typically have HW wallets.

Options: [May 18]

[added May 19]

Discussion: May 18:

Discussion: May 19:

idiom-bytes commented 2 years ago

[trentmc May 19: this comment was given when "Candidate 2" was still the leading candidate. But now we're doing "Candidate 3"]


Began implementing an "Admin Portall" w/ an Allocate dashboard.

Screenshot from 2022-05-18 15-07-30.png

TODO:

There is currently no security or permissions around this. Anyone can access this page. I have also taken the liberty of adding a link to the navbar.

trentmc commented 2 years ago

May 19 update:

(I updated the description to have more detail)

trentmc commented 2 years ago

Reopening, because it would be really nice if:

trizin commented 2 years ago

I was able to use an HW wallet with Brownie.

Here are the steps:

trentmc commented 2 years ago

Q: how to do a flow with gnosis safe multisig? A: the key is ape-safe. Here's the quickstart:

from ape_safe import ApeSafe
safe = ApeSafe('ychad.eth')

dai = safe.contract('0x6B175474E89094C44Da98b954EedeAC495271d0F')
vault = safe.contract('0x19D3364A399d251E894aC732651be8B0E4e85001')

amount = dai.balanceOf(safe.account)
dai.approve(vault, amount)
vault.deposit(amount)

safe_tx = safe.multisend_from_receipts()
safe.preview(safe_tx)
safe.post_transaction(safe_tx)

Flow where OPF spends the Ocean. Steps 1-3 do approve, steps 4-6 do allocate.

  1. Via dftool, someone create OCEAN.safeApprove(contract_addr, sum(values)) tx
  2. Via dftool, someone posts the tx to gnosis safe
  3. Inside Gnosis Safe app, >1 OPF people multisig-sign the pending tx
  4. Via dftool, someone create DFRewards.sol::allocate() tx
  5. Via dftool, someone posts the tx to gnosis safe
  6. Inside Gnosis Safe app, >1 OPF people multisig-sign the pending tx
trentmc commented 2 years ago

From some slack discussion...

[Berkay] Wouldn't it be simpler if: Multi sig transfers tokens to hw wallet Hw wallet calls allocate func

[Trent] Yes it's simpler

[Berkay] Do you think there is a security risk this in this approach?

[Trent] I had suggested the multisig because

  1. More secure yet. Though hw is very good tbh
  2. Flexibility: it's really easy to pass control among various addresses. Eg start out with a 1/1 multisig signed by a hw wallet. Later on if we want to have more control among more people, it's easy to do

Tbh I'm on the fence wrt this being worth it

Also, I'm not sure how well Gnosis safe will even support some of the chains

[Berkay] right + we will need to do it every week for each chain, might get complex to manage

[Trent] Good point!

And like mentioned, we can always re-deploy news contracts much later on. We'd probably do that when we automate more fully. That would be in 2023 sometime

To summarize: you're right. Just hw wallet is simpler. And will serve our needs for now. And we have a way to migrate later.

[Berkay] I fully agree, I wish there was an easy way to make it automatable and secure at the same time

trentmc commented 2 years ago

I just added instrs for HW wallets into df-py README

https://github.com/oceanprotocol/df-py/commit/09dca5f4dbbd15ec8065e99b6ec936dc072f0dda

We can now close this issue

trentmc commented 2 years ago

About multisig wallet:

Options / Steps

Below are three options (A, B, C), and the corresponding steps. Pre-step for all options:

Option A. Multisig -> Local account

  1. Generate local account via dftool newacct. Remember private key & address.
  2. For each chain: 2.1 tx: from multisig, send OCEAN -> local account https://github.com/oceanprotocol/atlantic/blob/master/logs/wallets.md

    2.2 check: does local account have funds for gas. If no: tx: from multisig, send funds for gas-> local account

    2.3 tx: from local account: dftool dispense

Option B. Multisig -> my hw wallet

  1. For each chain: 1.1 tx: from multisig, send OCEAN -> my hw wallet account https://github.com/oceanprotocol/atlantic/blob/master/logs/wallets.md

    1.2 check: does my hw wallet account have funds for gas. If no: tx: from multisig, send funds for gas -> my hw wallet account

    1.3 tx: from my hw wallet account: dftool dispense https://github.com/oceanprotocol/df-py/blob/main/README.md#usage-hardware-wallets

Option C. Direct from Multisig

  1. For each chain:
    • tx: from multisig: dftool dispense

Analysis Chosen approach: A for now

Steps for chosen approach

  1. inspect rewardsperlp-OCEAN.csv to see how much OCEAN each network needs
  2. Generate local account via dftool newacct. Remember private key & address.
  3. For each chain: 2.1 tx: from multisig, send OCEAN -> local account https://github.com/oceanprotocol/atlantic/blob/master/logs/wallets.md

    2.2 check: does local account have funds for gas. If no: tx: from multisig, send funds for gas-> local account

    2.3 tx: from local account: dftool dispense