Skip to content

Commit

Permalink
Merge branch 'v2' into v2-script
Browse files Browse the repository at this point in the history
  • Loading branch information
leekt authored Apr 22, 2024
2 parents f7c9af7 + 7681c9c commit 3338939
Show file tree
Hide file tree
Showing 11 changed files with 442 additions and 9 deletions.
15 changes: 14 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Kernel

> If you are looking for Kernel v3 source code, [it's sitting here](https://github.com/zerodevapp/kernel_v3) while we figure out how to merge it.
Kernel is a smart contract account that is:

- Compatible with [ERC-4337](https://eips.ethereum.org/EIPS/eip-4337).
Expand All @@ -13,7 +15,6 @@ Kernel is supported by all major AA SDKs, including:
- [ZeroDev](https://docs.zerodev.app/)
- [Permissionless.js](https://docs.pimlico.io/permissionless/how-to/accounts/use-kernel-account)
- [UserOp.js](https://docs.stackup.sh/docs/useropjs-presets#kernel)
- [Account Kit](https://github.com/alchemyplatform/aa-sdk/tree/main/packages/accounts/src/kernel-zerodev)

## Resources

Expand All @@ -36,6 +37,18 @@ MIT

## Addresses

<details>
<summary>v3.0</summary>

| Name | Address |
| -------------------- | ------------------------------------------ |
| Meta Factory | 0xd703aaE79538628d27099B8c4f621bE4CCd142d5 |
| Factory | 0x6723b44Abeec4E71eBE3232BD5B455805baDD22f |
| Kernel | 0x94F097E1ebEB4ecA3AAE54cabb08905B239A7D27 |
| ECDSA Validator | 0x8104e3Ad430EA6d354d013A6789fDFc71E671c43 |

</details>

<details>
<summary>v2.4</summary>

Expand Down
Binary file added audits/chainlight_v3_0.pdf
Binary file not shown.
Binary file added audits/kalos_v3_plugins.pdf
Binary file not shown.
120 changes: 120 additions & 0 deletions broadcast/DeployDeterministic.s.sol/137/run-1710798757.json

Large diffs are not rendered by default.

120 changes: 120 additions & 0 deletions broadcast/DeployDeterministic.s.sol/137/run-latest.json

Large diffs are not rendered by default.

120 changes: 120 additions & 0 deletions broadcast/DeployDeterministic.s.sol/80002/run-1710798602.json

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions script/DeployDeterministic.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import "./deterministic/SessionKey.s.sol";
import "./deterministic/Kernel2_2.s.sol";
import "./deterministic/Kernel2_3.s.sol";
import "./deterministic/Kernel2_4.s.sol";
import "./deterministic/FclWebAuthNValidator.s.sol";

contract DeployDeterministic is Script {
address constant DEPLOYER = 0x9775137314fE595c943712B0b336327dfa80aE8A;
Expand Down Expand Up @@ -40,6 +41,10 @@ contract DeployDeterministic is Script {
if (!factory.isAllowedImplementation(k24)) {
factory.setImplementation(k24, true);
}

// Deploy the webauthn fcl validators
FclWebAuthnValidatorDeploy.deployWebAuthnFclVerifier();

vm.stopBroadcast();
}
}
51 changes: 51 additions & 0 deletions script/deterministic/FclWebAuthNValidator.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
pragma solidity ^0.8.0;

import "src/utils/P256VerifierWrapper.sol";
import "src/validator/webauthn//WebAuthnFclValidator.sol";
import "./DeterministicDeploy.s.sol";
import "forge-std/console.sol";

/// @dev Deterministic deployment of FclWebAuthNValidator
library FclWebAuthnValidatorDeploy {
address constant EXPECTED_P256_VERIFIER_VALIDATOR_ADDRESS = 0x738e3257EE928637fE62c37F91D3e722C45Dcc7C;

address constant EXPECTED_WEBAUTHN_VALIDATOR_ADDRESS = 0x42085b533b27B9AfDAF3864a38c72eF853943DAB;

bytes32 constant DEPLOYMENT_SALT = keccak256("WebAuthNValidator by Frak");

/// @dev Deploy the P256VerifierWrapper and WebAuthnFclValidator
function deployWebAuthnFclVerifier() internal {
// Check if the contract of the p256 verifier is already deployed
if (EXPECTED_P256_VERIFIER_VALIDATOR_ADDRESS.code.length == 0) {
_deployOnChainP256();
} else {
console.log("P256VerifierWrapper: already deployed");
}

// Deploy the WebAuthnFclValidator
if (EXPECTED_WEBAUTHN_VALIDATOR_ADDRESS.code.length == 0) {
_deployValidator();
} else {
console.log("WebAuthnFclValidator: already deployed");
}
}

/// @dev Deploy the P256VerifierWrapper contract
function _deployOnChainP256() private {
P256VerifierWrapper p256Wrapper = new P256VerifierWrapper{salt: DEPLOYMENT_SALT}();
require(
address(p256Wrapper) == EXPECTED_P256_VERIFIER_VALIDATOR_ADDRESS,
"FclWebAuthnValidatorDeploy: p256 wrapper address mismatch"
);
}

/// @dev Deploy the P256VerifierWrapper contract
function _deployValidator() private {
WebAuthnFclValidator validator =
new WebAuthnFclValidator{salt: DEPLOYMENT_SALT}(EXPECTED_P256_VERIFIER_VALIDATOR_ADDRESS);
require(
address(validator) == EXPECTED_WEBAUTHN_VALIDATOR_ADDRESS,
"FclWebAuthnValidatorDeploy: validator address mismatch"
);
}
}
7 changes: 4 additions & 3 deletions src/validator/WeightedECDSAValidator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -104,15 +104,15 @@ contract WeightedECDSAValidator is EIP712, IKernelValidator {
{
require(weightedStorage[msg.sender].totalWeight != 0, "Not enabled");
address currentGuardian = weightedStorage[msg.sender].firstGuardian;
while (currentGuardian != msg.sender) {
while (currentGuardian != address(uint160(type(uint160).max))) {
address nextGuardian = guardian[currentGuardian][msg.sender].nextGuardian;
emit GuardianRemoved(currentGuardian, msg.sender);
delete guardian[currentGuardian][msg.sender];
currentGuardian = nextGuardian;
}
delete weightedStorage[msg.sender];
require(_guardians.length == _weights.length, "Length mismatch");
weightedStorage[msg.sender].firstGuardian = _guardians[0];
weightedStorage[msg.sender].firstGuardian = address(uint160(type(uint160).max));
_addGuardians(_guardians, _weights, msg.sender);
weightedStorage[msg.sender].delay = _delay;
weightedStorage[msg.sender].threshold = _threshold;
Expand Down Expand Up @@ -217,10 +217,11 @@ contract WeightedECDSAValidator is EIP712, IKernelValidator {
passed = true;
}
}
proposal.status = ProposalStatus.Executed;
if (passed && guardian[signer][msg.sender].weight != 0) {
proposal.status = ProposalStatus.Executed;
return packValidationData(ValidAfter.wrap(0), ValidUntil.wrap(0));
}
return SIG_VALIDATION_FAILED;
} else if (proposal.status == ProposalStatus.Approved || passed) {
if (userOp.paymasterAndData.length == 0 || address(bytes20(userOp.paymasterAndData[0:20])) == address(0)) {
address signer = ECDSA.recover(ECDSA.toEthSignedMessageHash(userOpHash), userOp.signature);
Expand Down
7 changes: 4 additions & 3 deletions src/validator/webauthn/WebAuthnFclValidator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ struct WebAuthnFclValidatorStorage {
/// @notice Inspired by the cometh Gnosis Safe signer: https://github.com/cometh-game/p256-signer
contract WebAuthnFclValidator is IKernelValidator {
/// @dev Event emitted when the public key signing the WebAuthN user operation is changed for a given `kernel`.
event WebAuthnPublicKeyChanged(address indexed kernel, uint256 x, uint256 y);
/// @dev The `b64AuthenticatorId` param represent the webauthn authenticator id used to create this public key
event WebAuthnPublicKeyChanged(address indexed kernel, string indexed b64AuthenticatorId, uint256 x, uint256 y);

/// @dev Mapping of kernel address to each webAuthn specific storage
mapping(address kernel => WebAuthnFclValidatorStorage webAuthnStorage) private webAuthnValidatorStorage;
Expand All @@ -44,13 +45,13 @@ contract WebAuthnFclValidator is IKernelValidator {
/// @dev Enable this validator for a given `kernel` (msg.sender)
function enable(bytes calldata _data) external payable override {
// Extract the x & y coordinates of the public key from the `_data` bytes
(uint256 x, uint256 y) = abi.decode(_data, (uint256, uint256));
(string memory authenticatorId, uint256 x, uint256 y) = abi.decode(_data, (string, uint256, uint256));
// Update the pub key data
WebAuthnFclValidatorStorage storage kernelValidatorStorage = webAuthnValidatorStorage[msg.sender];
kernelValidatorStorage.x = x;
kernelValidatorStorage.y = y;
// Emit the update event
emit WebAuthnPublicKeyChanged(msg.sender, x, y);
emit WebAuthnPublicKeyChanged(msg.sender, authenticatorId, x, y);
}

/// @dev Validate a `_userOp` using a WebAuthn Signature for the kernel account who is the `_userOp` sender
Expand Down
6 changes: 4 additions & 2 deletions test/foundry/validator/WebAuthnFclValidator.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,9 @@ contract WebAuthnFclValidatorTest is KernelTestBase {
}

function getInitializeData() internal view override returns (bytes memory) {
return abi.encodeWithSelector(KernelStorage.initialize.selector, webAuthNValidator, abi.encode(x, y));
return abi.encodeWithSelector(
KernelStorage.initialize.selector, webAuthNValidator, abi.encode("authenticator-id", x, y)
);
}

function test_default_validator_enable() external override {
Expand All @@ -76,7 +78,7 @@ contract WebAuthnFclValidatorTest is KernelTestBase {
IKernel.execute.selector,
address(webAuthNValidator),
0,
abi.encodeWithSelector(webAuthNValidator.enable.selector, abi.encode(x, y)),
abi.encodeWithSelector(webAuthNValidator.enable.selector, abi.encode("authenticator-id", x, y)),
Operation.Call
)
);
Expand Down

0 comments on commit 3338939

Please sign in to comment.