This is an implementation of the PoC contract for the Safe Wallet grant.
Our key concept is centered around the creation of a module for Safe multisig that ensures the anonymity of all its participants using ZK-SNARK technology.
The details are described in:
- Foundry
To get started with this project, you need to install Foundry. Follow the instructions here.
git clone https://github.com/oxor-io/sam-contracts.git
cd sam-contracts
foundryup
forge installBefore running tests, you will need to set up an .env file in the project root with an Ethereum API key. Create a .env file and add the following:
MAINNET_RPC={your-ethereum-api-key}
Replace your-ethereum-api-key with your actual API key. Then, you can run tests with the following command:
forge testFor detailed instructions on how to generate a proof, refer to the repository with circuit.
- 
Deployment and Initialization of the User Module Our module incorporates a proxy pattern, deployed through the SAM Factory using one of the following methods: - createProxyWithNonce
- createChainSpecificProxyWithNonce
- createProxyWithCallback
 Refer to the documentation for detailed descriptions of each method. For initialization, you can pass a payload when calling one of the aforementioned functions, which will then be executed by the newly created module. The information provided must align with the function call: function setup(address safe, uint256 participantsRoot, uint64 threshold) external; 
- 
Connecting the Module to Safe To link a module to Safe, Safe must invoke enableModule, passing the address of the created proxy as an argument.
- 
Transaction Execution Approval You can pre-approve a transaction execution. In this case, you need to provide all transaction parameters, including the nonce(the transaction number for the module account), and a set of proofs. The number of counted votes is proportional to the number of proofs submitted.function approveHash( address to, uint256 value, bytes memory data, ISafe.Operation operation, uint256 nonce, Proof[] calldata proofs ) external; 
- 
Executing the Transaction A transaction can only be executed once the proof threshold is met. This can occur through: - Submission of all proofs directly to one of the transaction execution functions.
- Granting permission for transaction execution using the approveHashfunction.
- A hybrid approach combining the above methods.
 There are two transaction execution functions: function executeTransaction( address to, uint256 value, bytes memory data, ISafe.Operation operation, Proof[] calldata proofs ) external returns (bool success); function executeTransactionReturnData( address to, uint256 value, bytes memory data, ISafe.Operation operation, Proof[] calldata proofs ) external returns (bool success, bytes memory returnData); The primary distinction is that the second function also returns the data from the transaction execution, while the first only returns the execution status. 
- 
Changing Module Parameters Two contract parameters can be modified: - threshold: the required number of votes to execute a transaction.
- participantsRoot: the root of the Merkle tree containing all participant addresses.
 The following function is used to modify these parameters: function file(bytes32 what, uint256 value) external; Here, whatrepresents either "root" or "threshold" in bytes32 type, depending on which parameter you wish to modify.Note: at this point, only the associated Safe can make changes. 
The code provided in this repository has not undergone a security audit. It is provided "as is" and without any warranty.
This project is licensed under the GNU General Public License v3.0 - see the LICENSE file for details.

