FuelLabs / FuelLabs/sway

Standard Ethereum signing support modules (for MetaMask, Ledger, Trezor and WalletConnect)

Open
#1,065 2 comments 1 reaction 0 assignees View on GitHub
enhancement lib: std
Dominant language
Rust
Stars
61.4k
Forks
5.4k
Avg merge
3h 33m
Merged PRs (30d)
4

Description

## Background

Fuel can support Ethereum signing schemes (commonly EIP-712 and the `eth_sign` RPC endpoint) via it's `keccak256` and `ecrecover` opcode in the FuelVM in combination with either a simple `predicate` script or basic proxy `contract`. This would allow for easy UX adoption from users / projects who use common Ethereum wallets / apps such as MetaMask, Ledger, Trezor and WalletConnect without the need for additional installation, apps, plugins or special key management.

We should provide an easily accessible set of modules / tools for Sway developers to leverage pre-built secure modules for this flow.

---

## Predicate Pseudo Code

```rs
predicate;

use std::address::*;
use std::metadata::witness;
use std::hash::keccak256;
use std::serialize::serialize_packed;

const owner = Address(0);

fn main() -> bool {
let digest = hash(
serialize_packed("Ethereum signed message/", tx_id()
), HashMethod::keccak256);

owner == ec_recover(digest, witness(0))
}
```

## Contract Pseudo Code

```rs
contract;

use std::address::*;
use std::metadata::witness;
use std::hash::keccak256;
use std::serialize::serialize_packed;

////////////////////////////////////////
// ABI declarations
////////////////////////////////////////

abi EthereumSignableWallet {
fn forward(destination: Address, data: Bytes);
}

////////////////////////////////////////
// Storage declarations
////////////////////////////////////////

const owner = Address(0); // this would be filled in at deployment.

////////////////////////////////////////
// Helper methods
////////////////////////////////////////

fn recover_ethereum_witness() -> Address {
let digest = keccak256(
serialize_packed("Ethereum signed message/", tx_id()
);

ec_recover(digest, witness(0))
}

////////////////////////////////////////
// ABI definitions
////////////////////////////////////////

impl EthereumSignableWallet for Contract {
fn forward(destination: Address, data: Bytes) {
assert(owner == recover_ethereum_witness());
call(destination, data)
}
}
```

---

Users can simply use their Ethereum wallets in our system, but will be required to either put their spendable deposits behind a restrictive predicate or put all their assets into a proxy contract.

## UX Flow Predicate Example
0) User has 1 Dai on Ethereum
1) Deposits 1 Dai into Fuel Bridge from Ethereum [asset it deposited to a predicate hash not their own address]
2) When spending 1 Dai in Fuel, user provides spendable deterministic predicate and necessary `eth_sign` signature to unlock assets.

## UX Flow Contract Proxy Example
0) User has 1 Dai on Ethereum
1) User or service creates simple stateless `EthereumSignableProxy` proxy contract on Fuel
2) User deposits 1 Dai into Fuel Bridge from Ethereum [asset is deposited to proxy contract address]
3) When spending 1 Dai in Fuel, user uses the proxy contract in Fuel to call other contracts and spend their assets by providing `eth_sign` signature to unlock contract.

## UX Flow Predicate + Contract Design (i.e. the Uniswap Flow)
0) User has 1 Dai on Ethereum
1) Deposits 1 Dai into Fuel Bridge from Ethereum [asset it deposited to a predicate hash not their own address]
2) User attempts to use App X, prompted with message, "In order to use App X you must have a proxy contract Y.. Deploy Now"
3) User creates simple stateless `EthereumSignableProxy` proxy contract on Fuel using some of the Dai to pay for deployment
4) User then uses App X

For most users, the contract is likely the best route, however, if we want a flow where the User pays for everything and there is no service in between we must do the third UX flow using both the predicate and smart-contract. Of course, that flow is the most complex.

This is very simpler to the use of DS-Proxy in many Uniswap or Dex Designs.

Contributor guide

No contributing guide indexed for this repository

Research direction

Start by reviewing the predicate and contract pseudo code in this issue alongside the existing keccak256, ecrecover, witness, and serialization capabilities it mentions. Define the scope and security requirements for reusable Ethereum signing modules covering MetaMask, Ledger, Trezor, and WalletConnect; done means an agreed implementation plan and accessible modules for Sway developers.

Written by the indexing model from the issue text.

Assessment

Domain
blockchain
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.