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

Commit

Permalink
feat: make SubnetRegistrator initializable
Browse files Browse the repository at this point in the history
Signed-off-by: Jawad Tariq <[email protected]>
  • Loading branch information
JDawg287 committed Sep 11, 2023
1 parent 69448cd commit c76d993
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 34 deletions.
14 changes: 9 additions & 5 deletions contracts/topos-core/SubnetRegistrator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ pragma solidity ^0.8.9;

import "./Bytes32Sets.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";

type SubnetId is bytes32;

contract SubnetRegistrator is Ownable {
contract SubnetRegistrator is Initializable, Ownable {
using Bytes32SetsLib for Bytes32SetsLib.Set;

struct Subnet {
Expand All @@ -30,10 +31,6 @@ contract SubnetRegistrator is Ownable {
/// @notice Subnet removal event
event SubnetRemoved(SubnetId subnetId);

constructor(address admin) Ownable() {
_transferOwnership(admin);
}

/// @notice Check if the subnet is already registered
/// @param subnetId FROST public key of a subnet
function subnetExists(SubnetId subnetId) external view returns (bool) {
Expand All @@ -51,6 +48,13 @@ contract SubnetRegistrator is Ownable {
return SubnetId.wrap(subnetSet.keyAtIndex(index));
}

/// @notice Contract initializer
/// @dev Can only be called once
/// @param admin address of the admin
function initialize(address admin) public initializer {
_transferOwnership(admin);
}

/// @notice Register a new subnet
/// @param endpoint JSON RPC endpoint of a subnet
/// @param logoURL URL for the logo of a subnet
Expand Down
107 changes: 78 additions & 29 deletions test/topos-core/SubnetRegistrator.test.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,37 @@
import { Contract } from 'ethers'
import { Contract, Wallet } from 'ethers'
import { ethers } from 'hardhat'
import { expect } from 'chai'

describe('SubnetRegistrator', () => {
let subnetRegistrator: Contract

const admin = '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266'
const endpoint = 'http://127.0.0.1'
const logoURL = 'http://image-url.com'
const subnetName = 'Test Subnet'
const subnetId = ethers.utils.formatBytes32String('subnetId')
const subnetCurrencySymbol = 'SUB'
const chainId = 1

beforeEach(async () => {
async function deploySubnetRegistratorFixture() {
const [admin, nonAdmin, toposDeployer] = await ethers.getSigners()
const SubnetRegistrator = await ethers.getContractFactory(
'SubnetRegistrator'
)
subnetRegistrator = await SubnetRegistrator.deploy(admin)
})
subnetRegistrator = await SubnetRegistrator.connect(toposDeployer).deploy()
await subnetRegistrator.deployed()
await subnetRegistrator.initialize(admin.address)
return {
admin,
nonAdmin,
subnetRegistrator,
toposDeployer,
}
}

describe('registerSubnet', () => {
it('reverts if non-admin tries to register a subnet', async () => {
const [, nonAdmin] = await ethers.getSigners()
const { nonAdmin, subnetRegistrator } =
await deploySubnetRegistratorFixture()
await expect(
subnetRegistrator
.connect(nonAdmin)
Expand All @@ -38,13 +47,17 @@ describe('SubnetRegistrator', () => {
})

it('reverts if the subnet is already registered', async () => {
const { admin, subnetRegistrator } =
await deploySubnetRegistratorFixture()
await registerSubnet(
endpoint,
logoURL,
subnetName,
subnetId,
subnetCurrencySymbol,
chainId
chainId,
subnetRegistrator,
admin
)
await expect(
registerSubnet(
Expand All @@ -53,19 +66,25 @@ describe('SubnetRegistrator', () => {
subnetName,
subnetId,
subnetCurrencySymbol,
chainId
chainId,
subnetRegistrator,
admin
)
).to.be.revertedWith('Bytes32Set: key already exists in the set.')
})

it('registers a subnet', async () => {
const { admin, subnetRegistrator } =
await deploySubnetRegistratorFixture()
await registerSubnet(
endpoint,
logoURL,
subnetName,
subnetId,
subnetCurrencySymbol,
chainId
chainId,
subnetRegistrator,
admin
)
const subnet = await subnetRegistrator.subnets(subnetId)
expect(subnet.name).to.equal(subnetName)
Expand All @@ -76,53 +95,69 @@ describe('SubnetRegistrator', () => {
})

it('gets the subnet count', async () => {
const { admin, subnetRegistrator } =
await deploySubnetRegistratorFixture()
await registerSubnet(
endpoint,
logoURL,
subnetName,
subnetId,
subnetCurrencySymbol,
chainId
chainId,
subnetRegistrator,
admin
)
const count = await subnetRegistrator.getSubnetCount()
expect(count).to.equal(1)
})

it('gets the subnet at a given index', async () => {
const { admin, subnetRegistrator } =
await deploySubnetRegistratorFixture()
await registerSubnet(
endpoint,
logoURL,
subnetName,
subnetId,
subnetCurrencySymbol,
chainId
chainId,
subnetRegistrator,
admin
)
const id = await subnetRegistrator.getSubnetIdAtIndex(0)
expect(id).to.equal(subnetId)
})

it('checks if a subnet exists', async () => {
const { admin, subnetRegistrator } =
await deploySubnetRegistratorFixture()
await registerSubnet(
endpoint,
logoURL,
subnetName,
subnetId,
subnetCurrencySymbol,
chainId
chainId,
subnetRegistrator,
admin
)
const exists = await subnetRegistrator.subnetExists(subnetId)
expect(exists).to.be.true
})

it('emits a new subnet registered event', async () => {
const { admin, subnetRegistrator } =
await deploySubnetRegistratorFixture()
await expect(
registerSubnet(
endpoint,
logoURL,
subnetName,
subnetId,
subnetCurrencySymbol,
chainId
chainId,
subnetRegistrator,
admin
)
)
.to.emit(subnetRegistrator, 'NewSubnetRegistered')
Expand All @@ -139,21 +174,27 @@ describe('SubnetRegistrator', () => {
})

it('reverts when removing a non-existent subnet', async () => {
await expect(removeSubnet(subnetId)).to.be.revertedWith(
'Bytes32Set: key does not exist in the set.'
)
const { admin, subnetRegistrator } =
await deploySubnetRegistratorFixture()
await expect(
removeSubnet(subnetId, subnetRegistrator, admin)
).to.be.revertedWith('Bytes32Set: key does not exist in the set.')
})

it('emit a subnet removed event', async () => {
const { admin, subnetRegistrator } =
await deploySubnetRegistratorFixture()
await registerSubnet(
endpoint,
logoURL,
subnetName,
subnetId,
subnetCurrencySymbol,
chainId
chainId,
subnetRegistrator,
admin
)
await expect(removeSubnet(subnetId))
await expect(removeSubnet(subnetId, subnetRegistrator, admin))
.to.emit(subnetRegistrator, 'SubnetRemoved')
.withArgs(subnetId)
})
Expand All @@ -165,19 +206,27 @@ describe('SubnetRegistrator', () => {
subnetName: string,
subnetId: string,
subnetCurrencySymbol: string,
chainId: number
chainId: number,
subnetRegistrator: Contract,
admin: Wallet
) {
return await subnetRegistrator.registerSubnet(
endpoint,
logoURL,
subnetName,
subnetId,
subnetCurrencySymbol,
chainId
)
return await subnetRegistrator
.connect(admin)
.registerSubnet(
endpoint,
logoURL,
subnetName,
subnetId,
subnetCurrencySymbol,
chainId
)
}

async function removeSubnet(subnetId: string) {
return await subnetRegistrator.removeSubnet(subnetId)
async function removeSubnet(
subnetId: string,
subnetRegistrator: Contract,
admin: Wallet
) {
return await subnetRegistrator.connect(admin).removeSubnet(subnetId)
}
})

0 comments on commit c76d993

Please sign in to comment.