add comments to contract

This commit is contained in:
Rishabh Gupta
2022-09-27 11:58:17 +05:30
parent 75ee37e391
commit b9436256ff
3 changed files with 156 additions and 53 deletions

View File

@@ -1,55 +1,66 @@
// SPDX-License-Identifier: MIT
pragma solidity^0.8.17;
pragma solidity ^0.8.17;
import "hardhat/console.sol";
import 'hardhat/console.sol';
interface IOtpMerkleTreeVerifier {
function verifyProof(
uint256[2] memory a,
uint256[2][2] memory b,
uint256[2] memory c,
uint256[2] memory input
) external view returns (bool);
function verifyProof(
uint256[2] memory a,
uint256[2][2] memory b,
uint256[2] memory c,
uint256[2] memory input
) external view returns (bool);
}
/// @title ZkOtpValidator
/// @author ZK Authentication team
/// @notice You can use this contract for verifying otp verification proof
/// @dev All function calls are currently implemented without side effects
contract ZkOtpValidator {
uint256 immutable root;
contract ZkOtpValidator{
address immutable verifier;
uint256 immutable root;
uint256 lastValidatedTimestamp;
address immutable verifier;
constructor(uint256 _root, address _verifier) {
root = _root;
verifier = _verifier;
}
uint256 lastValidatedTimestamp;
constructor(uint256 _root, address _verifier){
root = _root;
verifier = _verifier;
}
// modifier verify(
// uint256[2] memory a,
// uint256[2][2] memory b,
// uint256[2] memory c,
// uint256[2] memory input
// ) {
// require(input[0] == root, "Incoorect root");
// require(input[1] > lastValidatedTimestamp, "Old Proof");
// require(IOtpMerkleTreeVerifier(verifier).verifyProof(a, b, c, input), "Invalid proof");
// _;
// lastValidatedTimestamp = input[1];
// }
function verifyOTP(
uint256[2] memory a,
uint256[2][2] memory b,
uint256[2] memory c,
uint256[2] memory input
) public returns(bool success){
require(input[0] == root, "Incoorect root");
require(input[1] > lastValidatedTimestamp, "Old Proof");
require(IOtpMerkleTreeVerifier(verifier).verifyProof(a, b, c, input), "Invalid proof");
lastValidatedTimestamp = input[1];
success = true;
}
// modifier verify(
// uint256[2] memory a,
// uint256[2][2] memory b,
// uint256[2] memory c,
// uint256[2] memory input
// ) {
// require(input[0] == root, "Incoorect root");
// require(input[1] > lastValidatedTimestamp, "Old Proof");
// require(IOtpMerkleTreeVerifier(verifier).verifyProof(a, b, c, input), "Invalid proof");
// _;
// lastValidatedTimestamp = input[1];
// }
/**
* @notice Verify proof for OTP authentication
* @param a OTP verification proof from zk circuit
* @param b OTP verification proof from zk circuit
* @param c OTP verification proof from zk circuit
* @param Input public signals containing the Merkle root and time
*/
function verifyOTP(
uint256[2] memory a,
uint256[2][2] memory b,
uint256[2] memory c,
uint256[2] memory input
) public returns (bool success) {
require(input[0] == root, 'Incoorect root');
require(input[1] > lastValidatedTimestamp, 'Old Proof');
require(
IOtpMerkleTreeVerifier(verifier).verifyProof(a, b, c, input),
'Invalid proof'
);
lastValidatedTimestamp = input[1];
success = true;
}
}

View File

@@ -15,30 +15,48 @@ interface IHashCheckVerifier {
) external view returns (bool);
}
/// @title ZkSocialRecoveryWallet
/// @author ZK Authentication team
/// @notice You can use this contract for providing 2 factor authentication and social recovery
/// @dev All function calls are currently implemented without side effects
contract ZkSocialRecoveryWallet is IERC721Receiver, ZkOtpValidator {
/// Address of hash check verifier
address hashCheckVerifier;
/// Address of owner
address public owner;
/// password is not stored directly. We store the poseidon(public key user, password)
uint256 private ownerPasswordHash;
/// Minimum number of votes a new owner needs to get for execution
uint256 private thresholdForRecovery;
/// Unique counter for recovery rounds
uint256 public currentRecoveryNumber;
//to retrieve in frontend
/// Number of trustees(to retrieve in frontend)
uint256 public numberTrustees;
/// List of trustees
address[] public Trustees;
/// Map to find if an address is a trustee
mapping(address => bool) Trustee;
/// Map to store password hash corresponding to an address
mapping(address => uint256) trusteeToPasswordHash;
/// Map to store an owner and prevent trustees to use it again
mapping(address => bool) pastOwners;
/// Map to store if a proof is used
mapping(uint256 => bool) usedProofs;
/// Its true when recovery is in process
bool public isRecoveryOn;
/// Struct to store the variable required for the social recovery procedure
struct RecoveryProcedure {
uint256 numberOfVotesInSupport;
address newOwnerProposed;
@@ -46,6 +64,7 @@ contract ZkSocialRecoveryWallet is IERC721Receiver, ZkOtpValidator {
mapping(address => bool) trusteeSupporters;
}
/// Map to store the RecoveryProcedure for a recovery round number
mapping(uint256 => RecoveryProcedure) recoveryRoundNumberToProcedure;
event NewRecoveryProcedure(
@@ -116,18 +135,27 @@ contract ZkSocialRecoveryWallet is IERC721Receiver, ZkOtpValidator {
thresholdForRecovery = _thresholdForRecovery;
}
// To set trustees after deployment
/**
* @notice Set the trustees of a wallet after deployment
* @param _trustees the list of trustee addresses
*/
function setTrustees(address[] memory _trustees) external isOwner {
for (uint256 i = 0; i < _trustees.length; i++) {
for (uint256 i = 0; i < _trustees.length; i++) {
require(!Trustee[_trustees[i]], 'Duplicate trustee in list');
Trustee[_trustees[i]] = true;
}
Trustees = _trustees;
numberTrustees = _trustees.length;
}
}
// Set trustees password after deployment
function setTrusteesPasswords(uint256[] memory _passwordHashes) external isOwner {
/**
* @notice Set the trustees password's hash of a wallet after deployment
* @param _passwordHashes the list of trustee password hashes
*/
function setTrusteesPasswords(uint256[] memory _passwordHashes)
external
isOwner
{
require(
Trustees.length == _passwordHashes.length,
'Trustees and hashes length diff'
@@ -137,6 +165,14 @@ function setTrusteesPasswords(uint256[] memory _passwordHashes) external isOwner
}
}
/**
* @notice Start the recovery process
* @param a hash check proof from zk circuit
* @param b hash check proof from zk circuit
* @param c hash check proof from zk circuit
* @param Input public signals containing the password hash
* @param newOwner address of new owner
*/
function startRecovery(
uint256[2] memory a,
uint256[2][2] memory b,
@@ -171,6 +207,14 @@ function setTrusteesPasswords(uint256[] memory _passwordHashes) external isOwner
return currentRecoveryNumber;
}
/**
* @notice Vote in a recovery process already in process
* @param a hash check proof from zk circuit
* @param b hash check proof from zk circuit
* @param c hash check proof from zk circuit
* @param Input public signals containing the password hash
* @param recoveryRoundNumber current recovery round going on
*/
function voteInRecovery(
uint256[2] memory a,
uint256[2][2] memory b,
@@ -203,6 +247,14 @@ function setTrusteesPasswords(uint256[] memory _passwordHashes) external isOwner
emit VotedInRecovery(msg.sender, recoveryRoundNumber);
}
/**
* @notice Execute and finish the recovery process
* @param a hash check proof from zk circuit
* @param b hash check proof from zk circuit
* @param c hash check proof from zk circuit
* @param Input public signals containing the password hash
* @param recoveryRoundNumber current recovery round going on
*/
function executeRecoveryChange(
uint256[2] memory a,
uint256[2][2] memory b,
@@ -234,6 +286,14 @@ function setTrusteesPasswords(uint256[] memory _passwordHashes) external isOwner
emit RecoveryExecuted(old, owner, recoveryRoundNumber);
}
/**
* @notice Vote in a recovery process already in process
* @param a hash check proof from zk circuit
* @param b hash check proof from zk circuit
* @param c hash check proof from zk circuit
* @param Input public signals containing the password hash
* @param recoveryRoundNumber current recovery round going on
*/
function cancelRecovery(
uint256[2] memory a,
uint256[2][2] memory b,
@@ -251,6 +311,14 @@ function setTrusteesPasswords(uint256[] memory _passwordHashes) external isOwner
emit RecoveryCancelled(owner, recoveryRoundNumber);
}
/**
* @notice Execute a transaction after OTP verification
* @param a OTP verification proof from zk circuit
* @param b OTP verification proof from zk circuit
* @param c OTP verification proof from zk circuit
* @param Input public signals containing the Merkle root and time
* @param recoveryRoundNumber current recovery round going on
*/
function executeTxn(
uint256[2] memory a,
uint256[2][2] memory b,
@@ -260,7 +328,7 @@ function setTrusteesPasswords(uint256[] memory _passwordHashes) external isOwner
uint256 value
) external isOwner returns (bytes memory result) {
require(verifyOTP(a, b, c, input), 'Proof failed');
(bool success, bytes memory result) = callee.call{value: value}("");
(bool success, bytes memory result) = callee.call{value: value}('');
require(success, 'external call reverted');
// emit TransactionExecuted(callee, value, data);
return result;
@@ -275,5 +343,8 @@ function setTrusteesPasswords(uint256[] memory _passwordHashes) external isOwner
return this.onERC721Received.selector;
}
/**
* @notice recieve funds
*/
receive() external payable {}
}
}

View File

@@ -3,6 +3,10 @@ pragma solidity ^0.8.17;
import './ZkSocialRecoveryWallet.sol';
/// @title ZkWalletFactory
/// @author ZK Authentication team
/// @notice You can use this contract for deploying wallets having otp verification and social recovery
/// @dev All function calls are currently implemented without side effects
contract ZkWalletFactory {
mapping(address => address) public userAddressToWalletAddress;
event WalletCreated(address walletAddress);
@@ -13,6 +17,14 @@ contract ZkWalletFactory {
hashCheckVerifier = _hashCheckVerifier;
}
/**
* @notice Deploy a new wallet
* @param _ownerPasswordHash password is not stored directly. We store the poseidon(public key user, password)
* @param _thresholdForRecovery Minimum number of votes a new owner needs to get for execution
* @param _otpVerifier address of the otp verifier contract
* @param root merkle root value unique to a wallet which is later used in otp verification
* @return walletAddress address of new wallet
*/
function deployWallet(
uint256 _ownerPasswordHash,
uint256 _thresholdForRecovery,
@@ -32,7 +44,16 @@ contract ZkWalletFactory {
emit WalletCreated(walletAddress);
}
function getUserWalletAddress(address _user) external view returns(address _walletAddress) {
/**
* @notice Getter function to get user wallet address
* @param _user address
* @return walletAddress address of user wallet
*/
function getUserWalletAddress(address _user)
external
view
returns (address _walletAddress)
{
_walletAddress = userAddressToWalletAddress[_user];
}
}
}