joystream icon indicating copy to clipboard operation
joystream copied to clipboard

`Argo` Ethereum bridge vision

Open kdembler opened this issue 1 year ago • 4 comments

⚠️ Update: ⚠️ This version is outdated, please refer the comment below: https://github.com/Joystream/joystream/issues/5084#issuecomment-2051702479


For background see https://pioneerapp.xyz/#/forum/thread/859. In this document I will refer to:

  • locking native JOY to get newly minted Ethereum eJOY as wrapping,
  • burning eJOY to unlock native JOY as unwrapping.

Components

ERC20 eJOY token on Ethereum

We should use something premade like OpenZeppelin contracts. Contract needs to allow the owner (Eth Multisig) to mint new tokens. We should be able to use contracts provided by Sygma right away.

The only custom functionality we need is emitting some metadata when new tokens are minted, so we can automatically update status of transfers. Standard mint function available in OpenZeppelin only accepts destination and amount, but I think it could be possible to do some magic and include the mint metadata as part of additional calldata in the mint transaction for off-chain interpretation. If we manage to do that, maybe we could be able to use contracts provided by Sygma right away.

Bridge contract on Ethereum

We can go 2 ways about this:

It’s either only for utility, with no special powers. It would only contain a single burn function that would burn eJOY and emit event with metadata. It would basically be a burn contract.

Or additionally we allow this contract to mint eJOY on multisig behalf, see the discussion in Payments with metadata

Ethereum multisig

Doesn’t need anything fancy, most likely Gnosis Safe contracts. This multisig will be the owner of the ERC20 and will be able to mint new eJOY tokens.

Joystream multisig

Standard Joystream multisig that will be securing the treasury of locked JOY.

Indexing node

We need an indexing node that will connect Joystream and Ethereum chain data and keep track of all transfers. We can use Subsquid to index 2 chains at the same time. Would keep track of:

  1. All transfers and their status
  2. Multisig transactions and their status

Bridge UI

To make the process simple for both users and signers, we would need an app. It would allow:

  1. Connecting your Ethereum and Joystream wallets
  2. Bridging tokens in both directions
  3. Tracking status of transfers
  4. Multisig operations - signing and executing transactions on both Joystream and Ethereum side

Operations

Payments with metadata

For bridge operations, we need to be able to emit metadata so that indexing node can keep track of all the transfers. This is a bit tricky.

On Ethereum side, we need to keep track of minting and burning. Simple bridge contract can emit events on burn, but standard ERC20 mint doesn’t emit any data aside from recipient and amount. We can:

  1. Override standard mint ERC20 slightly to allow additional data - not recommended, could be problematic with later Sygma migration
  2. Give the bridge contract minting access, add mint function only callable by the multisig that mints new tokens and emits our custom event
  3. Try to manually encode additional metadata in EVM tx calldata, would be decoded by the indexing node. The downside is that there’s no visible event emitted in block explorer for example.

Here 2nd option is probably the way to go.

On Joystream side, we need to keep track of token transfer from and to the multisig treasury. Standard transfer doesn’t emit any additional data. We can:

  1. Limit bridge usage to accounts with memberships and use members.memberRemark that can send payment and emit metadata at the same time.
  2. Require users to use utility.batch with one call being transfer to the treasury and the other would be a system.remarkWithEvent with metadata. Indexing node would join the data.
  3. Experiment with manual encoding of calldata like on EVM side, not sure if possible

Here 2nd option also seems to be the best.

Example wrapping flow

  1. User goes to the app and connects their Joystream wallet.
  2. They use the UI to initiate a bridging to Ethereum. The UI create and executes a utility.batch transaction - balances.transfer sends X + fee JOY to the multsig treasury, system.remarkWithEvent emits the metadata containing the target Ethereum address.
  3. Indexing node picks up the event, creates a new transfer with pending status, assigns it an ID. It also creates a pending transaction for multisig signers to sign.
  4. Multisig signers use the app to browse pending transfers. They confirm the data and sign the pending transcation.
  5. Once signature threshold is reached, the transaction gets executed on the Ethereum side, calling mint function on the bridging contract that mints X new eJOY to a target wallet and emits an event with the bridge transfer ID.
  6. Indexing node picks up the event, marking the transfer as completed.

Example unwrapping flow

  1. User goes to the app and connects their Ethereum wallet.
  2. The app creates and executes a burn call to the bridging contract - it burns X eJOY, collects some ETH fee, and emits an event.
  3. Indexing node picks up the event, creates a new transfer.
  4. Multisig signers confirm the transfer.
  5. Transaction is executed on the Joystream side - utility.batch transferring X JOY from multisig treasury to the target address and emitting an event
  6. Indexing node picks up the event, marking the transfer as completed.

Fees

Unsure yet how to collect and manage fees. On Ethereum side, fee should be collected in ETH as to not impact the circulating supply of eJOY. It could be kept in the bridge contract and be withdrawable by the multsig. On Joystream side, fee can be only in JOY so we would need some procedure of withdrawing fee from the treasury without affecting number of locked funds. Alternatively, on Joystream side we could make the utility.batch have 3 calls - X JOY would go to the treasury but the fee would go to a separate account. This way the JOY treasury size would be always matching the circulating supply of eJOY.

Rough effort estimation

  • Deploy ERC20 - 5h
  • Develop and deploy bridge contract - 10h
  • Develop and deploy the indexing node - 20h
  • Develop the bridge UI - 80h
  • Prepare governance process for managing the bridge - 5h
  • Compliance - write terms of service that protects bridge operators, etc - 5h
  • Testing - 20h

Rough total - 145h

kdembler avatar Feb 25 '24 18:02 kdembler