GithubHelp home page GithubHelp logo

safe-global / safe-smart-account Goto Github PK

View Code? Open in Web Editor NEW
1.7K 41.0 842.0 9.25 MB

Safe allows secure management of blockchain assets.

Home Page: https://safe.global

License: GNU Lesser General Public License v3.0

JavaScript 5.22% Solidity 25.36% TypeScript 63.11% Shell 0.25% Makefile 0.11% Ruby 5.95%
ethereum wallet solidity

safe-smart-account's Introduction

Safe Smart Account

npm version Build Status Coverage Status

⚠️ This branch contains changes that are under development To use the latest audited version make sure to use the correct commit. The tagged versions that are used by the Safe team can be found in the releases.

Usage

Install requirements with npm:

npm i

Testing

To run the tests:

npm run build
npm run test

Optionally, if you want to run the ERC-4337 compatibility test, it uses a live bundler and node, so it contains some pre-requisites:

  1. Define the environment variables:
ERC4337_TEST_BUNDLER_URL=
ERC4337_TEST_NODE_URL=
ERC4337_TEST_SINGLETON_ADDRESS=
ERC4337_TEST_SAFE_FACTORY_ADDRESS=
MNEMONIC=
  1. Pre-fund the executor account derived from the mnemonic with some Native Token to cover the deployment of an ERC4337 module and the pre-fund of the Safe for the test operation.

Deployments

A collection of the different Safe contract deployments and their addresses can be found in the Safe deployments repository.

To add support for a new network follow the steps of the Deploy section and create a PR in the Safe deployments repository.

Deploy

⚠️ Make sure to use the correct commit when deploying the contracts. Any change (even comments) within the contract files will result in different addresses. The tagged versions that are used by the Safe team can be found in the releases.

Current version: The latest release is v1.3.0-libs.0 on the commit 767ef36

This will deploy the contracts deterministically and verify the contracts on etherscan using Solidity 0.7.6 by default.

Preparation:

  • Set MNEMONIC in .env
  • Set INFURA_KEY in .env
npm run deploy-all <network>

This will perform the following steps

npm run build
npx hardhat --network <network> deploy
npx hardhat --network <network> sourcify
npx hardhat --network <network> etherscan-verify
npx hardhat --network <network> local-verify

Custom Networks

It is possible to use the NODE_URL env var to connect to any EVM based network via an RPC endpoint. This connection then can be used with the custom network.

E.g. to deploy the Safe contract suite on that network you would run npm run deploy-all custom.

The resulting addresses should be on all networks the same.

Note: Address will vary if contract code is changed or a different Solidity version is used.

Replay protection (EIP-155)

Some networks require replay protection, making it incompatible with the default deployment process as it relies on a presigned transaction without replay protection (see https://github.com/Arachnid/deterministic-deployment-proxy).

Safe Smart Account contracts use a different deterministic deployment proxy (https://github.com/safe-global/safe-singleton-factory). To make sure that the latest version of this package is installed, make sure to run npm i --save-dev @gnosis.pm/safe-singleton-factory before deployment. For more information, including how to deploy the factory to a new network, please refer to the factory repo.

Note: This will result in different addresses compared to hardhat's default deterministic deployment process.

Verify contract

This command will use the deployment artifacts to compile the contracts and compare them to the onchain code

npx hardhat --network <network> local-verify

This command will upload the contract source to Etherescan

npx hardhat --network <network> etherscan-verify

Documentation

Audits/ Formal Verification

Security and Liability

All contracts are WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

License

All smart contracts are released under LGPL-3.0

safe-smart-account's People

Contributors

akshay-ap avatar cameel avatar denisgranha avatar dependabot[bot] avatar erak avatar georgi87 avatar jhoenicke avatar jpalvarezl avatar ldct avatar micahzoltu avatar mmv08 avatar nlordell avatar omahs avatar owl11 avatar pgrimaud avatar philogy avatar poolpitako avatar remedcu avatar renansouza2 avatar rmeissner avatar robriks avatar rodrigoherrerai avatar spalladino avatar subramanianv avatar surfingnerd avatar teryanarmen avatar uxio0 avatar xiaoxianboy avatar yanhuijessica avatar zhiqiangxu avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

safe-smart-account's Issues

Optimize GnosisSafe setup function

Inside the loop of setup method, every occurrence _owners[i] generates the code for loading from memory to stack. Recommendation: assign _owners[i] to an intermediate variable - it will result in smaller code, will consume less gas, and will be easier to audit.

Refactor contracts to use CREATE2 opcode

The CREATE2 opcode ethereum/py-evm#269 has been merged and will be available in the next hardfork. Safe contracts should use CREATE2 to simplify the on-boarding. All new safe proxy contracts should be created and setup via a proxy factory using the CREATE2 opcode. This way we can ensure that the address of the future Safe only depends on the setup arguments. The required salt for CREATE2 can be a constant in the proxy factory.

Consider using development branch

Currently feature branches are directly merged into master. Users might expect master branch contracts as audited. We should use a development branch for all changes, which were not audited by an external party. Contracts, which were not audited at all, should be removed from the master branch.

Add tests for ERC20 transfer

Outline

The GnosisSafe smart contract allows payment of transactions and creation with ERC20 tokens. As the ERC20 token standard did initially not define a return type for the transfer function there are different results for failing transfer:

  1. transfer returns false
  2. transfer reverts
  3. transfer throws and uses up all remaining gas

All different implementations should be tested with a failing and a successful transfer.

Acceptance Criteria

  • There are tests for all mentioned ERC20 token implementations of transfer (could be mocked via https://github.com/fleupold/mock-contract)
  • There are test cases for successful and failing payments of transactions (token as gasToken in GnosisSafe.execTransaction)
  • There are test cases for successful and failing payments of safe deployments (PayingProxy)
  • There are test cases for successful and failing transfers as a Safe transaction (send an ERC20 token from a Safe to another account)

Impossible to set correct gas price for gas tokens with low decimals

Description

When paying with an erc20 you would take the exchange rate of token to eth and calculate a fair gas price based on that. For the correct token gas price it is also necessary to take into consideration that eth has 18 and some tokens have less. This can cause problems because the gas price can potentially be between 0 and 1 (which is impossible with uint).

Example calculation

Used gas token will be LOVE (0xb3a4bc89d8517e0e2c9b66703d09d3029ffa1e6d)

  1. Eth gas price is 5 GWei = 5 000 000 000 Wei
  2. For a conversion rate of 1 LOVE = 0.01 ETH this would be multiplied by 100
  3. LOVE only has 6 decimals (compared to the 18 of ETH) therefore we need to divite by 1e12
    • Resulting token gas price: 0.5

Steps to reproduce

Add pipelining for multi send

It would be really useful if it is possible to "pipeline" MultiSend calls. The input of one multisend should be fowarded to the next multisend.

For this it would also be nice to allow staticcall and create as possible multisend operations.

Allow to define sender for meta-transaction

In the current implementation GnosisSafePersonalEdition.sol the refund is always sent to the tx.origin. In case the refund makes the transaction profitable for the sender there is the issue of front-running. Everyone would have the incentive to resubmit the transaction making other transactions fail. A solution to this would be to allow the client to define one specific sender address, which is the address to receive the refund. In case the client doesn't specify any address, the fallback could still be the tx.origin.

Merge Team Edition and Personal Edition

To allow a better integration for all clients and decrease the overhead of maintaining two different versions we should merge the two Gnosis Safe editions.

The new Gnosis Safe edition would have the following features:

  • Approve transactions with signatures (EIP-712)
  • Support contract signatures (EIP-1271) -> a Gnosis Safe can be an owner of a Gnosis Safe
  • Transactions have to be executed in order (nonce is stored on the Gnosis Safe contract)

Notes:

  • GnosisSafe.sol should be renamed to BaseSafe.sol
  • GnosisSafePersonalEdition.sol should be renamed to GnosisSafe.sol
  • GnosisSafeTeamEdition.sol will be removed

References: #43, #46, #47

Add solc package

The package.json does not list “solc” package, although it is required to run “truffle test”

Support for secp256r1 / mobile secure enclaves

From what I understand, the secure enclaves in Android and iOS use secp256r1 to generate signatures, whereas Ethereum uses secp256k1. This means the enclaves can't be used natively.

That said, Ethereum smart contracts are capable of verifying secp256r1 signatures, so a smart contract wallet should be able to use them to validate transactions. This would allow you to give any iOS or Android device the same level of security as a hardware wallet.

Assuming the above is true, would you consider supporting such functionality in Gnosis Safe? I think this is an excellent project, and would love to see it adopt all the industry best standards, rather than different wallets emerging for different functionality.

Ability to batch execute transactions

To save on fees, it would be very useful in the Counterfactual / Generalized State Channels use case to be able to batch transactions. Essentially making several executeTransaction calls in one transaction. Has this been discussed?

Add comment about the Solidity free memory pointer usage

In the fallback invocation, the Solidity free memory pointer (address 64) can be overwritten. It is currently not used in the code, but it is good to know if more code is added in the future. Recommendation: place comment about it in the code.

Make masterCopy state variable public

This would allow us to identify where the proxy is pointing (e.g. there is a recovery extension deployed by gnosis. Knowing the address would allow us to say this proxy points to a trusted master copy).

There is no disadvantage to making it public.

Use EIP712 when computing transaction hashes

EIP712 is a standard for hashing structured data in a way that the data schema is easily verifiable. This allows wallets to display the names, types, and values of all fields when signing a message, which reduces front-end attack vectors and makes signing arbitrary data safer.

Set up CI

In order to keep track of the break changes from Solidity, Testrpc and related libraries, would be nice to have a travis configuration, basic one, like:

travis.yml

language: node_js
node_js:
- '9'

This will install dependencies through npm install (need to add truffle to package.json) and run tests with npm test (need to add the testrpc node, use the same than gnosis-contracts https://github.com/gnosis/gnosis-contracts/blob/master/package.json#L37)

Allow to use nested Safes in Personal Edition

Currently only private key controlled accounts can be used to control the Personal Edition. We should allow to use Safe contracts as owners in other Safes. This can be done using EIP1271 by adding signatures of owning Safes to the signature byte array in the execTransactionAndPaySubmitter function. This way transaction fees would always be paid from the child Safe.

Error message when typing secutiry phrase

Prerequisites
-Having Gnosis Safe Wallet extension downloaded for Chrome.
-Having Gnosis Safe Wallet App downloaded for Android.

Steps to reproduce:
1- Accesing the App for Android
2- In Options, choose "Replace browser extension"
3- Scan QR code shown in browser extension
4- Try to type recovery phrase
5- Observe

Expected result:
The app and the extension are correctly syncronized

Actual result:
An error message is displayed while and after typing recovery phrase

img_20181022_110456175_hdr

Add local nonce

Create a new GnosisSafeTeamEdition.sol based on the current GnosisSafe.sol and use a local nonce instead of a global nonce.

Use single public key and offchain cryptographic methods

Context / issue

Right now, checkSignatures in Gnosis Safe uses a loop to define the threshold signature. This is inefficient and could be easily offloaded to the cryptographic protocol using a threshold signature requiring a single ECRECOVER instead of threshold times ECRECOVER.

Proposed solution

Replace the ECDSA verification loop by a simple ECDSA verification and off-loading the multisig using a cryptographic threshold signature

This would allow unlimited threshold size and cheaper contract executions. It was briefly discussed with @fleupold.
Here an implementation that would work as his for the Ethereum blockchain:
https://github.com/KZen-networks/multi-party-ecdsa

Gas price calculation for refunding tx gas

Context / issue

Currently there are 2 gas prices when sending a safe transaction:

  • The inner Safe tx gas price, which is signed by the user/s as part of the tx. From now on, innerGasPrice.
  • The tx gas price tx.gasprice, which is the gas price of the ethereum tx that triggers the Safe tx. From now on txGasPrice.

If the innerGasPrice > 0, a refund is sent to the sender of the tx, calculated using gasPrice * gasUsed (function handlePayment https://github.com/gnosis/safe-contracts/blob/development/contracts/GnosisSafe.sol#L106)

Problem is that if txGasPrice > innerGasPrice, sender pays more than the refund.

Proposed solution

Instead of using innerGasPrice for the refund, if can be used it as the maximum allowance of gas price to be refunded, so user will get the refund calculated using gas * min(innerGasPrice, txGasPrice). To be fair with the sender innerGasPrice would need to be a little overcalculated, so sender will not loose ether in the case that gas price increases.

Additional context

This will not apply for refunds using an ERC20 token.

Readme clarification

This line threw me off:

A Safe transaction has the same parameters as a regular Ethereum transaction: A destination address, an Ether value and a data payload as a bytes array. In addition, Safe transactions have two more parameters: operation and nonce.

nonce is already a field in a "regular Ethereum transaction". Are these additional parameters actually arguments to methods in a solidity contract? Or are they encoded as fields in a signed message? If the readme sentence is going to contrast against a regular transaction, it needs to address the nonce being part of both. (or maybe it's easier to just drop the reference to a regular transaction)

This is only part-way through my first read-through, and I expect it would become clear after reading more into it, but it's helpful for me when new people write these first-timer confusions up on my projects, so hopefully you feel the same. :)

Add name and version to eip712 domain

Context / issue

When signing a transaction for the Safe with MetaMask all information that are signed are being displayed. The domain object defines which the properties that should be verified/displayed about the target of the signature (in our case the Safe). Currently we only display the Safe address. As a minor improvement we could add the name ('GnosisSafe') and version ('0.0.2').

Proposed solution

Add name and version to EIP712 hash.

Issues

if we upgrade the master copy it is required to write a migration that updates the domain hash.

Abstract "owners" requirement out to default condition

Instead of forcing owner logic in the MultiSig, we could make owner logic a default condition of sorts. This way if someone wants to change the "owner" logic to something more they can do so without being potentially locked into the current owner logic.

The danger of this is that conditions would then have to provide their own owner logic, whereas now we have a more layered approach.

Just a thought ;)

Allow extension execution via meta transaction

To allow an external service to submit transactions executing extensions, we need to add support for meta-transactions. The global nonce has to be used to prevent replay attacks.

Suggested function signature:
function executeExtension(address to, uint256 value, bytes data, Operation operation, Extension extension, uint8 v, bytes32 r, bytes32 s)

Add test case for throwing delegatecall

If the delegatecall target (callee) throws instead of reverts, the output data will not be passed back to the proxy, and the returndatasize will return 0. Recommendation: There should be a test case covering this edge case.

Make approvedHashes public

Context / issue

There's no way to query the approvedHashes. It would be useful for tx relay/history services and maybe another use cases.

Proposed solution

approvedHashes should be public or there should be a function to access it, as it is with signedMessage (isValidSignature)

Add approveTransactionByHash(bytes32 hash) to Team Edition

To save gas it should be possible to approve a transaction by directly passing the hash instead of using approveTransactionWithParameters.

This would not store the parameters on the blockchain in any form and therefore an additional service is required.

Remove constructors from Safe contract and extensions, which only execute setup function.

Since setup function is called from the constructor, and can also be used standalone, the compiler actually generates two copies of this function. These copies are almost the same, the difference is in the way the input argument are read. When setup is called from the constructor, the input arguments are appended at the very end of the transaction data and are access by using CODECOPY. When setup is called standalone, the input arguments are accessed via CALLDATALOAD or CALLDATACOPY. Recommendation - remove call to setup from the GnosisSafe constructor. The master copy setup will require two transactions instead of one, but the benefit is shorter code and easier audit.

Logo Design Offer as Open Source Contribution

Hello Sir. I'm a UI/UX and Graphics Designer. I'm happy to see an open source project, So, I want provide a logo for you. Would you mind if I propose a new logo design for your project as my Open Source Contribution?

Thanks before.

_nonce argument not used

In function confirmTransaction, _nonce argument is not used, needs to be passed into the getTransactionHash call.

Implement EIP897 interface for proxy contract

Based on: ethereum/EIPs#897

Benefit:
Source code verification: right now when checking the code of a proxy in explorers
like Etherscan, it just shows the code in the proxy itself but not the actual
code of the contract. By standardizing this construct, they will be able to show
both the actual ABI and code for the contract.

Make execTransactionIfApproved handling of failed transactions in team addition consistent with personal edition

In the personal edition the nonce is increased even in case the transaction fails. We should have the same behavior for team edition: mark a transaction as executed even in case it fails and signal a failing transaction with an event. This prevents that transactions, which might not work at the time of transaction submission to remain forever in pending state and get lost, which is a potential security issue. Also execTransactionIfApproved should then return the success status of the transaction.

Favor use of the `gas` opcode over `not(0)`

In the Proxy and the Proxy factory contracts, more specifically in the calls each of these make here:

https://github.com/gnosis/gnosis-safe-contracts/blob/master/contracts/Proxy.sol#L27
https://github.com/gnosis/gnosis-safe-contracts/blob/master/contracts/ProxyFactory.sol#L21

Consider using the gas opcode (which is obviously only one instruction) over the current not(0) choice. It behaves exactly the same, compiles down to 1 vs 3 instructions and uses less gas.

Add events for Safe configuration changes

The following event should be added for configuration changes:

OwnerManager

AddedOwner(address owner) - An owner was added
RemovedOwner(address owner) - An owner was removed
ChangedThreshold(uint256 threshold) - The threshold was changed

Replacing an owner will trigger a RemovedOwner and AddedOwner event

ModuleManager

EnabledModule(Module module) - A module was enabled
DisabledModule(Module module) - A module was disabled

MultiSend Condition Option

We might want to write a mutli-send whitelist condition, just so we can restrict multi-send delegatecall tx's with a condition.

Perhaps we can use the same condition API. Not sure how we would go about the assembly.

The problem with even the whitelist exception is that if it delegatecalls to a multisend than it defeats the purpose of the restriction. Might want to do some more thinking around this.

Comment masterCopy usage

Use comments in both GnosisSafe.sol and Proxy.sol that masterCopy fields are related to each other and to MUST stay in the same storage index for the upgradeability to work, and for the safety of using GnosisSafe via Proxy.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.