Skip to content

Commit

Permalink
Create a folder with experimental contracts, deploy webauthsignerfactory
Browse files Browse the repository at this point in the history
  • Loading branch information
mmv08 committed Jan 12, 2024
1 parent b37e394 commit 463e313
Show file tree
Hide file tree
Showing 12 changed files with 71 additions and 4 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/certora.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ jobs:
with: { java-version: "17", java-package: jre, distribution: semeru }

- name: Install certora cli
run: pip install -Iv certora-cli
run: pip install -Iv certora-cli==5.0.5

- name: Install solc
run: |
Expand Down
2 changes: 1 addition & 1 deletion 4337/.prettierignore
Original file line number Diff line number Diff line change
@@ -1 +1 @@
contracts/test/FCL/**/*.sol
contracts/vendor/FCL/**/*.sol
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@

// SPDX-License-Identifier: LGPL-3.0-only
/* solhint-disable one-contract-per-file */
pragma solidity >=0.8.0;

import {FCL_WebAuthn} from "./FCL/FCL_Webauthn.sol";
import {FCL_WebAuthn} from "../vendor/FCL/FCL_Webauthn.sol";
import {IUniqueSignerFactory} from "./SafeSignerLaunchpad.sol";

struct SignatureData {
Expand Down Expand Up @@ -35,26 +36,55 @@ function checkSignature(bytes memory data, bytes calldata signature, uint256 x,
}
}

/**
* @title WebAuthnSigner
* @dev A contract that represents a WebAuthn signer.
*/
contract WebAuthnSigner {
uint256 public immutable X;
uint256 public immutable Y;

/**
* @dev Constructor function.
* @param x The X coordinate of the signer's public key.
* @param y The Y coordinate of the signer's public key.
*/
constructor(uint256 x, uint256 y) {
X = x;
Y = y;
}

/**
* @dev Validates the signature for the given data.
* @param data The signed data bytes.
* @param signature The signature to be validated.
* @return magicValue The magic value indicating the validity of the signature.
*/
function isValidSignature(bytes memory data, bytes calldata signature) external view returns (bytes4 magicValue) {
return checkSignature(data, signature, X, Y);
}
}

/**
* @title WebAuthnSignerFactory
* @dev A factory contract for creating and managing WebAuthn signers.
*/
contract WebAuthnSignerFactory is IUniqueSignerFactory {
/**
* @dev Retrieves the signer address based on the provided data.
* @param data Concatenated X and Y coordinates of the signer as bytes.
* @return signer The address of the signer.
*/
function getSigner(bytes calldata data) public view returns (address signer) {
(uint256 x, uint256 y) = abi.decode(data, (uint256, uint256));
signer = _getSigner(x, y);
}

/**
* @dev Creates a new signer based on the provided data.
* @param data Concatenated X and Y coordinates of the signer as bytes.
* @return signer The address of the newly created signer.
*/
function createSigner(bytes calldata data) external returns (address signer) {
(uint256 x, uint256 y) = abi.decode(data, (uint256, uint256));
signer = _getSigner(x, y);
Expand All @@ -64,6 +94,13 @@ contract WebAuthnSignerFactory is IUniqueSignerFactory {
}
}

/**
* @dev Checks if the provided signature is valid for the given signer.
* @param data The signed data as bytes.
* @param signature The signature to be verified.
* @param signerData The data used to identify the signer. In this case, the X and Y coordinates of the signer.
* @return magicValue The magic value indicating the validity of the signature.
*/
function isValidSignatureForSigner(
bytes memory data,
bytes calldata signature,
Expand All @@ -73,11 +110,22 @@ contract WebAuthnSignerFactory is IUniqueSignerFactory {
magicValue = checkSignature(data, signature, x, y);
}

/**
* @dev Retrieves the signer address based on the provided coordinates.
* @param x The x-coordinate of the signer.
* @param y The y-coordinate of the signer.
* @return The address of the signer.
*/
function _getSigner(uint256 x, uint256 y) internal view returns (address) {
bytes32 codeHash = keccak256(abi.encodePacked(type(WebAuthnSigner).creationCode, x, y));
return address(uint160(uint256(keccak256(abi.encodePacked(hex"ff", address(this), bytes32(0), codeHash)))));
}

/**
* @dev Checks if the provided account has no code.
* @param account The address of the account to check.
* @return True if the account has no code, false otherwise.
*/
function _hasNoCode(address account) internal view returns (bool) {
uint256 size;
// solhint-disable-next-line no-inline-assembly
Expand Down
2 changes: 1 addition & 1 deletion 4337/contracts/test/TestUniqueSigner.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
pragma solidity >=0.8.0;

import {ISignatureValidator} from "@safe-global/safe-contracts/contracts/interfaces/ISignatureValidator.sol";
import {IUniqueSignerFactory} from "./SafeSignerLaunchpad.sol";
import {IUniqueSignerFactory} from "../experimental/SafeSignerLaunchpad.sol";

function checkSignature(bytes memory data, uint256 signature, uint256 key) pure returns (bytes4 magicValue) {
uint256 message = uint256(keccak256(data));
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
19 changes: 19 additions & 0 deletions 4337/src/deploy/webauthn.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { DeployFunction } from 'hardhat-deploy/types'

const deploy: DeployFunction = async ({ deployments, getNamedAccounts, network }) => {
if (!network.tags.dev && !network.tags.test) {
return
}

const { deployer } = await getNamedAccounts()
const { deploy } = deployments

await deploy('WebAuthnSignerFactory', {
from: deployer,
args: [],
log: true,
deterministicDeployment: true,
})
}

export default deploy

0 comments on commit 463e313

Please sign in to comment.