Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: update registry deployment script to latest #130

Merged
merged 13 commits into from
Aug 28, 2024
3 changes: 3 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ jobs:
match-path: "test/**/*.sol"
secrets:
MAINNET_RPC_URL: ${{ secrets.MAINNET_RPC_URL }}
TESTNET_RPC_URL: ${{ secrets.TESTNET_RPC_URL }}

test-simulate:
needs: ["lint", "build"]
Expand All @@ -31,6 +32,7 @@ jobs:
match-path: "test/**/*.sol"
secrets:
MAINNET_RPC_URL: ${{ secrets.MAINNET_RPC_URL }}
TESTNET_RPC_URL: ${{ secrets.TESTNET_RPC_URL }}

test-multi-account:
needs: ["lint", "build"]
Expand All @@ -41,3 +43,4 @@ jobs:
match-path: "test/**/*.sol"
secrets:
MAINNET_RPC_URL: ${{ secrets.MAINNET_RPC_URL }}
TESTNET_RPC_URL: ${{ secrets.TESTNET_RPC_URL }}
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@rhinestone/modulekit",
"version": "0.4.11",
"version": "0.4.12",
"description": "A development kit for building and testing smart account modules.",
"license": "GPL-3.0",
"author": {
Expand Down Expand Up @@ -34,6 +34,7 @@
"@rhinestone/module-bases": "github:rhinestonewtf/module-bases",
"@rhinestone/safe7579": "github:rhinestonewtf/safe7579#v1.0.0",
"@rhinestone/sentinellist": "github:rhinestonewtf/sentinellist",
"@rhinestone/registry": "github:rhinestonewtf/registry#v1.0",
"@safe-global/safe-contracts": "^1.4.1",
"@zerodev/kernel": "github:kopy-kat/kernel#patch",
"ds-test": "github:dapphub/ds-test",
Expand Down
450 changes: 240 additions & 210 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions remappings.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ erc4337-validation/=node_modules/@rhinestone/erc4337-validation/src/
safe7579/=node_modules/@rhinestone/safe7579/src/
modulekit/=node_modules/@rhinestone/modulekit/src/
module-bases/=node_modules/@rhinestone/module-bases/src/
registry/=node_modules/@rhinestone/registry/src/

@ERC4337/=node_modules/@ERC4337/
account-abstraction/=node_modules/@ERC4337/account-abstraction/contracts/
Expand Down
289 changes: 129 additions & 160 deletions src/deployment/RegistryDeployer.sol
Original file line number Diff line number Diff line change
@@ -1,211 +1,180 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.23;

import { IERC165 } from "forge-std/interfaces/IERC165.sol";
import { IRegistry, IExternalResolver } from "registry/IRegistry.sol";
import {
ResolverRecord,
ModuleRecord,
ResolverUID,
AttestationRecord,
AttestationRequest,
ModuleType,
SchemaUID,
SchemaRecord
} from "registry/DataTypes.sol";
import { IExternalSchemaValidator } from "registry/external/IExternalSchemaValidator.sol";

address constant REGISTRY_ADDR = 0x000000000069E2a187AEFFb852bF3cCdC95151B2;

address constant REGISTRY_ADDR = 0xe0cde9239d16bEf05e62Bbf7aA93e420f464c826;
contract RegistryDeployer {
IRegistry internal registry = IRegistry(REGISTRY_ADDR);

// Struct that represents Module artefact.
struct ModuleRecord {
bytes32 resolverUID; // The unique identifier of the resolver.
address sender; // The address of the sender who deployed the contract
bytes metadata; // Additional data related to the contract deployment
}
// Default resolver
ResolverUID internal resolverUID =
ResolverUID.wrap(0xdbca873b13c783c0c9c6ddfc4280e505580bf6cc3dac83f8a0f7b44acaafca4f);

struct ResolverRecord {
address resolver; // Optional resolver.
address resolverOwner; // The address of the account used to register the resolver.
}
SchemaUID internal schemaUID =
SchemaUID.wrap(0x93d46fcca4ef7d66a413c7bde08bb1ff14bacbd04c4069bb24cd7c21729d7bf1);

struct AttestationRecord {
bytes32 schemaUID; // The unique identifier of the schema.
address subject; // The recipient of the attestation i.e. module
address attester; // The attester/sender of the attestation.
uint48 time; // The time when the attestation was created (Unix timestamp).
uint48 expirationTime; // The time when the attestation expires (Unix timestamp).
uint48 revocationTime; // The time when the attestation was revoked (Unix timestamp).
address dataPointer; // SSTORE2 pointer to the attestation data.
}
address internal mockAttester = 0xA4C777199658a41688E9488c4EcbD7a2925Cc23A;

contract RegistryDeployer {
IRegistry internal registry = IRegistry(REGISTRY_ADDR);
// Default resolver
bytes32 internal resolverUID =
0xdf658e5595d93baa803af242dc6e175b4cbef04de73509b50b944d1b2d167bb6;
error InvalidResolver();

// <---- DEPLOYMENT ---->

function deployModule(
bytes memory code,
bytes memory deployParams,
bytes memory initCode,
bytes32 salt,
bytes memory data
bytes memory metadata,
bytes memory resolverContext
)
public
returns (address moduleAddr)
{
bytes32 _resolverUID = getResolver();
moduleAddr = registry.deploy(code, deployParams, salt, data, _resolverUID);
ResolverUID _resolverUID = findResolver();
moduleAddr = registry.deployModule({
resolverUID: _resolverUID,
initCode: initCode,
salt: salt,
metadata: metadata,
resolverContext: resolverContext
});
}

function deployModuleCreate3(
bytes memory code,
bytes memory deployParams,
bytes32 salt,
bytes memory data
function deployModuleViaFactory(
address factory,
bytes memory callOnFactory,
bytes memory metadata,
bytes memory resolverContext
)
public
returns (address moduleAddr)
{
bytes32 _resolverUID = getResolver();
moduleAddr = registry.deployC3(code, deployParams, salt, data, _resolverUID);
ResolverUID _resolverUID = findResolver();
moduleAddr = registry.deployViaFactory({
factory: factory,
callOnFactory: callOnFactory,
metadata: metadata,
resolverUID: _resolverUID,
resolverContext: resolverContext
});
}

function deployModuleViaFactory(
address factory,
bytes memory callOnFactory,
bytes memory data
function predictModuleAddress(
bytes32 salt,
bytes memory initCode
)
public
view
returns (address)
{
return registry.calcModuleAddress(salt, initCode);
}

// <---- ATTESTATIONS ---->

function mockAttestToModule(
address module,
bytes memory attestationData,
ModuleType[] memory moduleTypes
)
public
returns (address moduleAddr)
{
bytes32 _resolverUID = getResolver();
moduleAddr = registry.deployViaFactory(factory, callOnFactory, data, _resolverUID);
require(isContract(mockAttester), "MockAttester is not deployed on this network");

SchemaUID _schemaUID = findSchema();
AttestationRequest memory request = AttestationRequest({
moduleAddress: module,
expirationTime: 0,
data: attestationData,
moduleTypes: moduleTypes
});
(bool success,) = mockAttester.call(
abi.encodeWithSignature(
"attest(address,bytes32,(address,uint48,bytes,uint256[]))",
REGISTRY_ADDR,
_schemaUID,
request
)
);

require(success, "Mock attestation failed");
}

function isModuleAttestedMock(address module) public view returns (bool) {
AttestationRecord memory attestation =
registry.findAttestation({ module: module, attester: mockAttester });
return attestation.time > 0 && attestation.expirationTime < block.timestamp
&& attestation.revocationTime == 0;
}

// <---- REGISTRY MANAGEMENT ---->

function getResolver() public view returns (bytes32 _resolverUID) {
function findResolver() public view returns (ResolverUID _resolverUID) {
_resolverUID = resolverUID;
ResolverRecord memory resolver = registry.getResolver(resolverUID);
ResolverRecord memory resolver = registry.findResolver(resolverUID);
if (address(resolver.resolver) == address(0)) {
revert InvalidResolver();
}
}

function registerResolver(address resolver) public returns (bytes32 _resolverUID) {
_resolverUID = registry.registerResolver(IResolver(resolver));
function registerResolver(address resolver) public returns (ResolverUID _resolverUID) {
_resolverUID = registry.registerResolver(IExternalResolver(resolver));
}

function findSchema() public view returns (SchemaUID _schemaUID) {
_schemaUID = schemaUID;
SchemaRecord memory schema = registry.findSchema(schemaUID);
if (schema.registeredAt == 0) {
revert InvalidResolver();
}
}

function registerSchema(
string memory schema,
address validator
)
public
returns (SchemaUID _schemaUID)
{
_schemaUID = registry.registerSchema({
schema: schema,
validator: IExternalSchemaValidator(validator)
});
}

function getModule(address moduleAddress) public view returns (ModuleRecord memory) {
return registry.getModule(moduleAddress);
function findModule(address moduleAddress) public view returns (ModuleRecord memory) {
return registry.findModule(moduleAddress);
}

function setRegistry(address _registry) public {
registry = IRegistry(_registry);
}

function setResolverUID(bytes32 _resolverUID) public {
function setResolverUID(ResolverUID _resolverUID) public {
resolverUID = _resolverUID;
}

error InvalidResolver();
}

// Interfaces

interface IResolver is IERC165 {
/**
* @dev Returns whether the resolver supports ETH transfers.
*/
function isPayable() external pure returns (bool);

/**
* @dev Processes an attestation and verifies whether it's valid.
*
* @param attestation The new attestation.
*
* @return Whether the attestation is valid.
*/
function attest(AttestationRecord calldata attestation) external payable returns (bool);

/**
* @dev Processes a Module Registration
*
* @param module Module registration artefact
*
* @return Whether the registration is valid
*/
function moduleRegistration(ModuleRecord calldata module) external payable returns (bool);

/**
* @dev Processes multiple attestations and verifies whether they are valid.
*
* @param attestations The new attestations.
* @param values Explicit ETH amounts which were sent with each attestation.
*
* @return Whether all the attestations are valid.
*/
function multiAttest(
AttestationRecord[] calldata attestations,
uint256[] calldata values
)
external
payable
returns (bool);

/**
* @dev Processes an attestation revocation and verifies if it can be revoked.
*
* @param attestation The existing attestation to be revoked.
*
* @return Whether the attestation can be revoked.
*/
function revoke(AttestationRecord calldata attestation) external payable returns (bool);

/**
* @dev Processes revocation of multiple attestation and verifies they can be revoked.
*
* @param attestations The existing attestations to be revoked.
* @param values Explicit ETH amounts which were sent with each revocation.
*
* @return Whether the attestations can be revoked.
*/
function multiRevoke(
AttestationRecord[] calldata attestations,
uint256[] calldata values
)
external
payable
returns (bool);
}

interface IRegistry {
function deploy(
bytes calldata code,
bytes calldata deployParams,
bytes32 salt,
bytes calldata data,
bytes32 resolverUID
)
external
payable
returns (address moduleAddr);

function deployC3(
bytes calldata code,
bytes calldata deployParams,
bytes32 salt,
bytes calldata data,
bytes32 resolverUID
)
external
payable
returns (address moduleAddr);

function deployViaFactory(
address factory,
bytes calldata callOnFactory,
bytes calldata data,
bytes32 resolverUID
)
external
payable
returns (address moduleAddr);

function registerResolver(IResolver _resolver) external returns (bytes32);

function getResolver(bytes32 uid) external view returns (ResolverRecord memory);
function setSchemaUID(SchemaUID _schemaUID) public {
schemaUID = _schemaUID;
}

function getModule(address moduleAddress) external view returns (ModuleRecord memory);
// <---- OTHER ---->
function isContract(address _addr) internal returns (bool isContract) {
uint32 size;
assembly {
size := extcodesize(_addr)
}
return (size > 0);
}
}
Loading