Skip to content
This repository has been archived by the owner on Jan 11, 2024. It is now read-only.

Diamond registry #153

Merged
merged 36 commits into from
Jul 26, 2023
Merged
Show file tree
Hide file tree
Changes from 24 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 60 additions & 8 deletions scripts/deploy-registry.template
Original file line number Diff line number Diff line change
@@ -1,26 +1,78 @@
import hre, { ethers } from 'hardhat';
import { getTransactionFees } from './util';
import { ethers } from 'hardhat';
import { deployContractWithDeployer, getTransactionFees } from './util';

async function main() {
try {
const { getSelectors } = require('./js/diamond.js')

await hre.run('compile');
const GATEWAY = '0x4A04DDb64568C5721f6387a6e85FE1585cF7AB9e';
cryptoAtwill marked this conversation as resolved.
Show resolved Hide resolved
const LIBMAP = {
cryptoAtwill marked this conversation as resolved.
Show resolved Hide resolved
AccountHelper: '0x66678Fc409698D82b3e410fd7DA2c66D7c3519Ad',
CheckpointHelper: '0xA09a74EbE98A67a8EB7bdA5ed7723Dd4c7E0A738',
EpochVoteSubmissionHelper: '0xBe824993678eF316eB3572CcAcDc9bD25138952D',
ExecutableQueueHelper: '0x5B3C5AE1dFEa8D6E2cDE31D3C26dEFbB27e4E2A9',
SubnetIDHelper: '0x9cd4b43C82bcC717b88e3D85F53B71c2947357A2',
CrossMsgHelper: '0xefAdA657fE12557Ab515625b4b39C6797df2c843',
};

async function main() {
try {
const [deployer] = await ethers.getSigners();
const balance = await deployer.getBalance();

console.log(`Deploying contracts with account: ${deployer.address} and balance: ${balance.toString()}`);

const gatewayAddress = GATEWAY.Gateway;
const gatewayAddress = GATEWAY;
cryptoAtwill marked this conversation as resolved.
Show resolved Hide resolved
const txArgs = await getTransactionFees();

// deploy
const registry = await ethers.getContractFactory('SubnetRegistry', { signer: deployer, libraries: LIBMAP });
const contract = await registry.deploy(gatewayAddress, txArgs);
const getterFacet = await deployContractWithDeployer(
deployer,
"SubnetActorGetterFacet",
{},
txArgs
);
const getterSelectors = getSelectors(getterFacet);
console.log("getter address:", getterFacet.address, "selectors:", getSelectors);

const managerFacet = await deployContractWithDeployer(
deployer,
"SubnetActorManagerFacet",
LIBMAP,
cryptoAtwill marked this conversation as resolved.
Show resolved Hide resolved
txArgs
);
const managerSelectors = getSelectors(managerFacet);
console.log("manager address:", managerFacet.address, "selectors:", managerSelectors);

const registry = await ethers.getContractFactory('SubnetRegistry', { signer: deployer, libraries: {
"SubnetIDHelper": LIBMAP["SubnetIDHelper"]
}});

const contract = await registry.deploy(
gatewayAddress,
getterFacet.address,
managerFacet.address,
getterSelectors,
managerSelectors,
txArgs
);

// FEVM:
console.log(`registry contract deployed to: ${contract.address}`);


const constructorParams = {
parentId: { root: 31415926, route: [] },
cryptoAtwill marked this conversation as resolved.
Show resolved Hide resolved
name: ethers.utils.formatBytes32String('Subnet'),
ipcGatewayAddr: GATEWAY,
consensus: 0,
minActivationCollateral: ethers.utils.parseEther("1"),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We may need to set this one to 1FIL not one Ether (I don't think the units match).

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

they are all 18 decimals right?

minValidators: 3,
bottomUpCheckPeriod: 10,
topDownCheckPeriod: 10,
majorityPercentage: 66,
genesis: 0
};
await contract.newSubnetActor(constructorParams);

process.exit(0);
} catch (error) {
console.error(error);
Expand Down
19 changes: 19 additions & 0 deletions src/CloneFactory.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.19;

//solhint-disable max-line-length
//solhint-disable no-inline-assembly

contract CloneFactory {
function createClone(address target) internal returns (address result) {
bytes20 targetBytes = bytes20(target);
assembly {
let clone := mload(0x40)
mstore(clone, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)
cryptoAtwill marked this conversation as resolved.
Show resolved Hide resolved
mstore(add(clone, 0x14), targetBytes)
mstore(add(clone, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)
result := create(0, clone, 0x37)
}
}
}
3 changes: 1 addition & 2 deletions src/SubnetActorDiamond.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,9 @@ import {IDiamond} from "./interfaces/IDiamond.sol";
import {GatewayCannotBeZero, NotGateway, InvalidMajorityPercentage} from "./errors/IPCErrors.sol";
import {LibDiamond} from "./lib/LibDiamond.sol";
import {LibVoting} from "./lib/LibVoting.sol";
import {SubnetID, Subnet} from "./structs/Subnet.sol";
import {SubnetID} from "./structs/Subnet.sol";
import {SubnetIDHelper} from "./lib/SubnetIDHelper.sol";
import {Status} from "./enums/Status.sol";
import {GatewayDiamond} from "./GatewayDiamond.sol";

error FunctionNotFound(bytes4 _functionSelector);

Expand Down
90 changes: 49 additions & 41 deletions src/SubnetRegistry.sol
Original file line number Diff line number Diff line change
@@ -1,24 +1,21 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.19;

import {SubnetActor} from "./SubnetActor.sol";
import {SubnetID} from "./structs/Subnet.sol";
import {SubnetIDHelper} from "./lib/SubnetIDHelper.sol";
import {SubnetActorDiamond} from "./SubnetActorDiamond.sol";
import {IDiamond} from "./interfaces/IDiamond.sol";
import {CloneFactory} from "./CloneFactory.sol";

contract SubnetRegistry {
using SubnetIDHelper for SubnetID;

/// @notice Mapping that tracks the deployed subnet actors per user.
/// Key is the hash of Subnet ID, values are addresses.
/// mapping owner => nonce => subnet
mapping(address => mapping(uint64 => address)) public subnets;
contract SubnetRegistry is CloneFactory {
address public immutable gateway;

/// @notice Mapping that tracks the latest nonce of the deployed
/// subnet for each user.
/// owner => nonce
mapping(address => uint64) public userNonces;
/// The base contract address for clone factory
cryptoAtwill marked this conversation as resolved.
Show resolved Hide resolved
address public getterFacet;
address public managerFacet;

address public immutable gateway;
/// The subnet getter facet functions selectors
bytes4[] public subnetGetterSelectors;
/// The subnet manager facet functions selectors
bytes4[] public subnetManagerSelectors;

/// @notice Event emitted when a new subnet is deployed.
event SubnetDeployed(address subnetAddr);
Expand All @@ -27,41 +24,52 @@ contract SubnetRegistry {
error ZeroGatewayAddress();
error UnknownSubnet();

constructor(address _gateway) {
if (_gateway == address(0)) {
revert ZeroGatewayAddress();
}
constructor(
address _gateway,
address _getterFacet,
address _managerFacet,
bytes4[] memory _subnetGetterSelectors,
bytes4[] memory _subnetManagerSelectors
) {
gateway = _gateway;

getterFacet = _getterFacet;
managerFacet = _managerFacet;

subnetGetterSelectors = _subnetGetterSelectors;
subnetManagerSelectors = _subnetManagerSelectors;
}

function newSubnetActor(SubnetActor.ConstructParams calldata params) external returns (address subnetAddr) {
if (params.ipcGatewayAddr != gateway) {
/// @notice Deploys a new subnet actor.
/// @param _params The constructor params for Subnet Actor.
cryptoAtwill marked this conversation as resolved.
Show resolved Hide resolved
function newSubnetActor(
SubnetActorDiamond.ConstructorParams calldata _params
) external returns (address subnetAddr) {
if (_params.ipcGatewayAddr != gateway) {
revert WrongGateway();
}

subnetAddr = address(new SubnetActor(params));
IDiamond.FacetCut[] memory diamondCut = new IDiamond.FacetCut[](2);

subnets[msg.sender][userNonces[msg.sender]] = subnetAddr;
++userNonces[msg.sender];
// set the diamond cut for subnet getter
diamondCut[0] = IDiamond.FacetCut({
facetAddress: createClone(getterFacet),
cryptoAtwill marked this conversation as resolved.
Show resolved Hide resolved
action: IDiamond.FacetCutAction.Add,
functionSelectors: subnetGetterSelectors
});

emit SubnetDeployed(subnetAddr);
}
// set the diamond cut for subnet manager
diamondCut[1] = IDiamond.FacetCut({
facetAddress: address(managerFacet),
action: IDiamond.FacetCutAction.Add,
functionSelectors: subnetManagerSelectors
});

/// @notice Returns the address of the latest subnet actor
/// deployed by a user
function latestSubnetDeployed(address owner) external view returns (address subnet) {
subnet = subnets[owner][userNonces[owner] - 1];
if (subnet == address(0)) {
revert ZeroGatewayAddress();
}
}
// we can reduce gas by using clone factory as well, but it
cryptoAtwill marked this conversation as resolved.
Show resolved Hide resolved
// involves quite some change, will use clone factory is
// gas is a big issue.
subnetAddr = address(new SubnetActorDiamond(diamondCut, _params));

/// @notice Returns the address of a subnet actor deployed for a
/// specific nonce by a user
function getSubnetDeployedByNonce(address owner, uint64 nonce) external view returns (address subnet) {
subnet = subnets[owner][nonce];
if (subnet == address(0)) {
revert ZeroGatewayAddress();
}
emit SubnetDeployed(subnetAddr);
}
}
4 changes: 2 additions & 2 deletions test/SubnetRegistry.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ contract SubnetRegistryTest is Test {
SubnetRegistry sr;

function setUp() public {
sr = new SubnetRegistry(DEFAULT_IPC_GATEWAY_ADDR);
sr = new SubnetRegistry(DEFAULT_IPC_GATEWAY_ADDR, new bytes4[](0), new bytes4[](0));
}

function test_Registry_Deployment_Works() public {
Expand All @@ -53,7 +53,7 @@ contract SubnetRegistryTest is Test {
uint8 _majorityPercentage
) public {
vm.startPrank(DEFAULT_SENDER);
SubnetActor.ConstructParams memory params = SubnetActor.ConstructParams({
SubnetActorDiamond.ConstructorParams memory params = SubnetActorDiamond.ConstructorParams({
parentId: SubnetID({root: ROOTNET_CHAINID, route: new address[](0)}),
name: _name,
ipcGatewayAddr: _ipcGatewayAddr,
Expand Down