Try   HackMD

Fun Wallet Smart Contracts

POV: you are a developer looking to integrate the fun.xyz wallet SDK

Features

Assets

  • Transfer and hold erc20, erc721, and erc1155 tokens with approve, transfer, and permit

Developer Fees

  • Set flat developer fees on a per transaction basis or as a percentage of gas, paid in either ERC20 tokens or the native gas token

Dealing with Gas

  • Sponsor transactions for Funwallets using a gasless paymaster, charging the gasSponsor address instead of a funwallet address
    • Whitelist (allow specific addresses and no one else) or blacklist(allow all addresses besides specific addresses) from getting gasless transactions
  • Allow funwallets to charge users in ERC20-tokens instead of paying for gas.
    • the funwallet calls approve() or permit() the token paymaster to spend their ETH
    • the funwallet sends a transaction
    • the TokenPriceOracle.sol calculates the token:gas price and takes a corresponding amount of tokens from the funwallet's approve

Access Control

  • Role based access control: Funwallets grant address roles, each role can have specific rule(s) attached to them
  • A rule can either be a function rule or a target rule.
    • a selector rule specifies a function. anyone with the rule in that funwallet can call that function
    • a target rule specifies a target contract and function, anyone can call that function on the target contract
    • a user rule specifies a user and a function, only that user can call that function
    • You can also specify constraints on rules, such as ensuring the value of a piece of data is less than some value
  • Multisignatures on a single user operation from the fun wallet

Note: is the target rule even useful? You can just call an arbitrary contract with a given target rule, ie badToken.approve() and get all your funds drained since you don't know what badToken.approve() does

Defi

  • Approve and swap eth and erc20 tokens in one transaction
  • Approve and execute arbitrary logic in one transaction
  • Withdraw from aave in one transaction

Misc

  • Create a wallet from your twitter handle with a deterministic address such that you can send crypto to twitter handles.
  • Use the same address on all fun.xyz supported chains via Create3
  • Allow fun.xyz to create modules that can execute arbitrary logic from Funwallets

Design Decisions

  • Explain the pipeline of the create3 deployer: Why does it start where it does and what is the purpose of everything

  • Go through functions that are uncommented and add them

  • Draw a picture for whitelist/blacklist mode for tokens

    • Why is add/remove token data only for the owner and not per sponsor. Why do we expect someone to deploy their own paymaster if they want to use their own token?(univ2 vs univ4)
  • If RBAC is a new design, explain the design, if it is the same design but with structs instead of assembly, explain the validation and why it is so complex

  • What is the purpose of modules, and why do we have an approve and exec and approve and swap module and nothing else?

    • ApproveAndExec could literally just be exec or just two function calls, why specifically approve and exec
    • Why do we assume that the swap uses a router and router callData, is this meant to be generalized or just for uniswap
  • Which contracts are meant to be deployed and standalone and which contracts are not?

  • Why is FunWallet inheriting all this stuff in such a weird way? Ie wallet exec, then overriding functions with walletxec in the funwallet? In object oriented programming, you inherit from abstract classes if you are making a more detailed class, but it seems like we are just inheriting stuff since we don't want to put those functions in Funwallet.sol

  • Why do we have this random _transferERC20 function in funwallet.sol

  • What is the purpose of sigTimeRange

  • If you are going to add assembly, add comments explaining what it does and why this is better than not using asembly, ie requireFromModule

  • Encodepacked vs using all this assembly

  • Userauth: ECDSA. Used to verify users have some ownership of some ID. _validateSignatureECDSA()

  • Remove functions from hashlib

  • Change how we do error handling

  • Refactor abstract contracts,

  • Use libraries instead of abstract contracts

  • Look at entrypoint v6 and nonce manager

  • hardcode address in approve and swap, passed in in the constructor

  • batching instead of modules since we can just have rbac rules in batching

Role based access control

RBAC: Create a system where users in the wallet can give access to users to use certain functions. Optimize for gas costs

All features in the Funwallet are expected to be executed from execFromEntrypoint(address target, uint256 value, bytes calldata) or execFromEntrypointWithFee(address target, uint256 value, bytes calldata)

There are two parts to call execFromEntrypoint, the access control flow and the execution flow.

The core concept of RBAC is the role:

struct Role {
    bool allowlistMode; 
    uint256 deadline;
    bytes32 targetSelectorMerkleRoot;
}

allowlistMode: default false, will only allow targetSelectors in the targetSelectorMerkleRoot