Skip to content

Commit

Permalink
Making chain id manager owner less (#168)
Browse files Browse the repository at this point in the history
* refactors of the smart contracts - using error instead of reverts and minor modifications

* linting

* making the ChainIdManager ownerless

* better comments
  • Loading branch information
josojo authored Jan 5, 2024
1 parent a82b25b commit 7283b89
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 15 deletions.
27 changes: 17 additions & 10 deletions contracts/ChainIdManager.sol
Original file line number Diff line number Diff line change
@@ -1,34 +1,41 @@
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity ^0.8.20;

import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
// The ChainIdManager contract provides a list of new usable chainIds via the getNextUsableChainId function.
// If a project uses one chainId, it can be added to the deny list and then no other project will use it.
// The contract does not come with an owner, but anyone can add chainIds to the deny list.
// It costs just gasBurnAmount to deny list a chainId.
// The burnGas function introduces this cost to use up chainIds.
// There are uint64(2**63=9.223372e+18) chainIds minus the publicly used chainIds available.
// Using all of the chainIds would cost 9.223372e+18 * gasBurnAmount = 9.223372e+24 gas = 6.1489147e+17 blocks = 237226647377 years

contract ChainIdManager is Ownable {
contract ChainIdManager {
// Counter for the number of Chain IDs
uint64 public chainIdCounter = 0;
// contains a list of denied Chain IDs that should not be used as chainIds
// they are governed by a owner of the contract
// they are anyone who is willing to pay the gas to use them.
mapping(uint64 => bool) public deniedChainIds;
// Fee to use up a Chain ID
// Fee to use up a chain ID
uint256 public immutable gasBurnAmount = 1000000;

constructor(uint64 _chainIdCounter) Ownable() {
constructor(uint64 _chainIdCounter) {
chainIdCounter = _chainIdCounter;
}

/**
* @dev Adds a Chain ID to the deny list, this can be done if the chainId is used by another project
* @param chainId The Chain ID to add
*/
function denyListChainId(uint64 chainId) public onlyOwner {
function denyListChainId(uint64 chainId) public {
burnGas();
deniedChainIds[chainId] = true;
}

/**
* @dev Adds multiple Chain IDs to the deny list
* @param chainIds The Chain IDs to add
*/
function denyListChainIds(uint64[] memory chainIds) public onlyOwner {
function denyListChainIds(uint64[] memory chainIds) public {
for (uint256 i = 0; i < chainIds.length; i++) {
denyListChainId(chainIds[i]);
}
Expand All @@ -39,9 +46,6 @@ contract ChainIdManager is Ownable {
* @return chainId The next usable Chain ID
*/
function getNextUsableChainId() public returns (uint64 chainId) {
// The burnGas function introduces a cost to use up chainIds.
// There are uint64(2**63=9.223372e+18) chainIds minus the publicly used chainIds available.
// Using all of the chainIds would cost 9.223372e+18 * gasBurnAmount = 9.223372e+24 gas = 6.1489147e+17 blocks = 237226647377 years
burnGas();
while (deniedChainIds[chainIdCounter]) {
chainIdCounter++;
Expand All @@ -50,6 +54,9 @@ contract ChainIdManager is Ownable {
chainIdCounter++;
}

/**
* @dev Burns gasBurnAmount gas to incure a cost for everyone calling this function
*/
function burnGas() public view {
uint256 counter = 0;
uint256 _lowestLimit = gasleft() - gasBurnAmount;
Expand Down
21 changes: 16 additions & 5 deletions test/ChainIdManager.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,9 @@ contract ChainIdManagerTest is Test {

function setUp() public {
chainIdManager = new ChainIdManager(initialChainId);
chainIdManager.transferOwnership(owner);
}

function testAddChainId() public {
vm.prank(owner);
uint64 newChainId = 10;
chainIdManager.denyListChainId(newChainId);

Expand All @@ -27,10 +25,23 @@ contract ChainIdManagerTest is Test {
"Chain ID not correctly added"
);

// Attempt to add a ChainId by a non-owner, expect a revert
vm.prank(nonOwner);
vm.expectRevert(bytes("Ownable: caller is not the owner")); // Expect a revert with a specific revert message
// Attempt to add a ChainId by a non-owner, expect a consumption of gas
uint256 currentGas = gasleft();
chainIdManager.denyListChainId(2);
uint256 finalGas = gasleft();
assert(currentGas - finalGas >= chainIdManager.gasBurnAmount());

uint256 currentGas2 = gasleft();
uint64[] memory newChainIds = new uint64[](6);
newChainIds[0] = 3;
newChainIds[1] = 4;
newChainIds[2] = 5;
newChainIds[3] = 6;
newChainIds[4] = 7;
newChainIds[5] = 8;
chainIdManager.denyListChainIds(newChainIds);
uint256 finalGas2 = gasleft();
assert(currentGas2 - finalGas2 >= chainIdManager.gasBurnAmount() * 6);
}

function testAddChainIds() public {
Expand Down

0 comments on commit 7283b89

Please sign in to comment.