diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ef160eb3..4458e476 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -31,3 +31,4 @@ jobs: key: ${{ runner.os }}-modules-${{ hashFiles('**/yarn.lock') }} - run: yarn --frozen-lockfile - run: yarn build + - run: yarn test diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index acddebe5..de433065 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -25,7 +25,7 @@ jobs: key: ${{ runner.os }}-modules-${{ hashFiles('**/yarn.lock') }} - run: yarn --frozen-lockfile - run: yarn build - #- run: yarn test + - run: yarn test publish-npm: needs: build diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 792b1aac..fa9524ce 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -35,7 +35,7 @@ jobs: key: ${{ runner.os }}-modules-${{ hashFiles('**/yarn.lock') }} - run: yarn --frozen-lockfile - run: yarn build - #- run: yarn test + - run: yarn test bump_version: name: Bump Version @@ -123,15 +123,21 @@ jobs: SOLIDITY_SETTINGS: ${{ matrix.settings }} steps: - uses: actions/checkout@v3 + with: + ref: ${{ github.ref }} + fetch-depth: 0 + - uses: actions/setup-node@v3 with: node-version: 16.7.0 registry-url: https://registry.npmjs.org/ always-auth: true + - uses: actions/cache@v3 with: path: "**/node_modules" key: ${{ runner.os }}-modules-${{ hashFiles('**/yarn.lock') }} + - run: yarn --frozen-lockfile - run: yarn publish env: diff --git a/.github/workflows/update-version.yml b/.github/workflows/update-version.yml index 7d1a4b41..fa7bca40 100644 --- a/.github/workflows/update-version.yml +++ b/.github/workflows/update-version.yml @@ -2,15 +2,11 @@ name: Bump npm version on: pull_request: - branches: - - 'development' - types: - - opened - - edited - - synchronize + branches: [development] + types: [opened, edited, synchronize] # manual trigger - #workflow_dispatch: + workflow_dispatch: jobs: bump_version: @@ -18,9 +14,10 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout Source Code - uses: 'actions/checkout@v2' + uses: 'actions/checkout@v3' with: - ref: ${{ github.ref }} + ref: ${{ github.event.pull_request.head.sha }} + fetch-depth: 0 - name: cat package.json run: cat ./package.json @@ -31,9 +28,10 @@ jobs: # we skip tag, as a new tag is created when the release workflow is executed with: skip-tag: 'true' - bump-policy: 'all' - minor-wording: 'feat,feature' - patch-wording: 'fix,patch' + target-branch: 'development' + #bump-policy: 'all' + #minor-wording: 'feat,feature,feat:' + #patch-wording: 'fix,patch,fix:' default: prerelease env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/contracts/protocol/dragoRegistry/DragoRegistry.sol b/contracts/protocol/dragoRegistry/DragoRegistry.sol index a2f19788..90f29ffc 100644 --- a/contracts/protocol/dragoRegistry/DragoRegistry.sol +++ b/contracts/protocol/dragoRegistry/DragoRegistry.sol @@ -19,11 +19,12 @@ pragma solidity 0.8.14; -import { Owned } from "../../utils/owned/Owned.sol"; -import { IDragoRegistry } from "../interfaces/IDragoRegistry.sol"; +import { OwnedUninitialized as Owned } from "../../utils/owned/OwnedUninitialized.sol"; import { IAuthority as Authority } from "../interfaces/IAuthority.sol"; import { LibSanitize } from "../../utils/LibSanitize/LibSanitize.sol"; +import { IDragoRegistry } from "../interfaces/IDragoRegistry.sol"; + /// @title Drago Registry - Allows registration of pools. /// @author Gabriele Rigo - // solhint-disable-next-line @@ -40,27 +41,20 @@ contract DragoRegistry is IDragoRegistry, Owned { Drago[] dragos; - mapping (bytes32 => address) mapFromKey; mapping (address => uint256) mapFromAddress; - mapping (string => uint256) mapFromName; + mapping (bytes32 => address) mapFromKey; + mapping (bytes32 => uint256) mapFromName; struct Drago { address drago; - string name; - string symbol; + bytes32 name; + bytes32 symbol; uint256 dragoId; address owner; address group; mapping (bytes32 => bytes32) meta; } - /* - * EVENTS - */ - event Registered(string name, string symbol, uint256 id, address indexed drago, address indexed owner, address indexed group); - event Unregistered(string indexed name, string indexed symbol, uint256 indexed id); - event MetaChanged(uint256 indexed id, bytes32 indexed key, bytes32 value); - /* * MODIFIERS */ @@ -80,12 +74,16 @@ contract DragoRegistry is IDragoRegistry, Owned { } modifier whenNameFree(string memory _name) { - require(mapFromName[_name] == 0); + require( + mapFromName[bytes32(bytes(_name))] == 0, + "REGISTRY_NAME_ALREADY_REGISTERED_ERROR" + ); _; } modifier whenNameSanitized(string memory _input) { - require(bytes(_input).length >= 4 && bytes(_input).length <= 50); + // we always want to keep name lenght below 32, for logging bytes32. + require(bytes(_input).length >= 4 && bytes(_input).length <= 32); require(LibSanitize.isValidCheck(_input)); _; } @@ -98,7 +96,10 @@ contract DragoRegistry is IDragoRegistry, Owned { } modifier whenHasName(string memory _name) { - require(mapFromName[_name] != 0); + require( + mapFromName[bytes32(bytes(_name))] != 0, + "REGISTRY_POOL_DOES_NOT_HAVE_NAME_ERROR" + ); _; } @@ -108,24 +109,28 @@ contract DragoRegistry is IDragoRegistry, Owned { _; } - constructor(address _authority) { + constructor( + address _authority, + address _owner + ) + { AUTHORITY = _authority; + owner = _owner; } /* * CORE FUNCTIONS */ - /// @dev Allows a factory which is an authority to register a pool - /// @param _drago Address of the pool - /// @param _name Name of the pool - /// @param _symbol Symbol of the pool - /// @param _dragoId Id number of the pool - /// @param _owner Address of the pool owner + /// @dev Allows a factory which is an authority to register a pool. + /// @param _drago Address of the pool. + /// @param _name Name of the pool. + /// @param _symbol Symbol of the pool. + /// @param _owner Address of the pool owner. + /// @return poolId Id of the new pool. function register( address _drago, string calldata _name, string calldata _symbol, - uint256 _dragoId, address _owner) external payable @@ -135,9 +140,9 @@ contract DragoRegistry is IDragoRegistry, Owned { whenNameSanitized(_name) whenSymbolSanitized(_symbol) whenNameFree(_name) - returns (bool) + returns (uint256 poolId) { - return registerAs(_drago, _name, _symbol, _dragoId, _owner, msg.sender); + return registerAs(_drago, _name, _symbol, _owner, msg.sender); } /// @dev Allows owner to unregister a pool @@ -146,10 +151,10 @@ contract DragoRegistry is IDragoRegistry, Owned { external onlyOwner { - emit Unregistered(dragos[_id].name, dragos[_id].symbol, _id); delete mapFromAddress[dragos[_id].drago]; delete mapFromName[dragos[_id].name]; delete dragos[_id]; + emit Unregistered(dragos[_id].name, dragos[_id].symbol, _id); } /// @dev Allows pool owner to set metadata for a pool @@ -254,7 +259,8 @@ contract DragoRegistry is IDragoRegistry, Owned { /// @return owner Pool struct data /// @return group Pool struct data function fromId(uint256 _id) - public view //prev external + public + view //prev external returns ( address drago, string memory name, @@ -264,10 +270,16 @@ contract DragoRegistry is IDragoRegistry, Owned { address group ) { + bytes memory bytesName = new bytes(32); + bytes memory bytesSymbol = new bytes(32); + for (uint256 i; i < 32; i++) { + bytesName[i] = dragos[_id].name[i]; + bytesSymbol[i] = dragos[_id].symbol[i]; + } return ( drago = dragos[_id].drago, - name = dragos[_id].name, - symbol = dragos[_id].symbol, + name = string(bytesName), + symbol = string(bytesSymbol), dragoId = dragos[_id].dragoId, owner = getPoolOwner(drago), group = dragos[_id].group @@ -293,11 +305,17 @@ contract DragoRegistry is IDragoRegistry, Owned { address group ) { - id = mapFromAddress[_drago] - 1; + id = mapFromAddress[_drago]; + bytes memory bytesName = new bytes(32); + bytes memory bytesSymbol = new bytes(32); + for (uint256 i; i < 32; i++) { + bytesName[i] = dragos[id].name[i]; + bytesSymbol[i] = dragos[id].symbol[i]; + } return ( id, - name = dragos[id].name, - symbol = dragos[id].symbol, + name = string(bytesName), + symbol = string(bytesSymbol), dragoId = dragos[id].dragoId, owner = getPoolOwner(_drago), group = dragos[id].group @@ -323,11 +341,15 @@ contract DragoRegistry is IDragoRegistry, Owned { address group ) { - id = mapFromName[_name] - 1; + id = mapFromName[bytes32(bytes(_name))]; + bytes memory bytesSymbol = new bytes(32); + for (uint256 i; i < 32; i++) { + bytesSymbol[i] = dragos[id].symbol[i]; + } return ( id, drago = dragos[id].drago, - symbol = dragos[id].symbol, + symbol = string(bytesSymbol), dragoId = dragos[id].dragoId, owner = getPoolOwner(drago), group = dragos[id].group @@ -341,8 +363,12 @@ contract DragoRegistry is IDragoRegistry, Owned { external view returns (string memory) { - uint256 id = mapFromAddress[_pool] - 1; - return dragos[id].name; + uint256 id = mapFromAddress[_pool]; + bytes memory bytesName = new bytes(32); + for (uint256 i; i < 32; i++) { + bytesName[i] = dragos[id].name[i]; + } + return string(bytesName); } /// @dev Provides a pool's symbol from its address @@ -352,8 +378,12 @@ contract DragoRegistry is IDragoRegistry, Owned { external view returns (string memory) { - uint256 id = mapFromAddress[_pool] - 1; - return dragos[id].symbol; + uint256 id = mapFromAddress[_pool]; + bytes memory bytesSymbol = new bytes(32); + for (uint256 i; i < 32; i++) { + bytesSymbol[i] = dragos[id].symbol[i]; + } + return string(bytesSymbol); } /// @dev Provides a pool's metadata @@ -392,30 +422,29 @@ contract DragoRegistry is IDragoRegistry, Owned { /// @param _drago Address of the pool /// @param _name Name of the pool /// @param _symbol Symbol of the pool - /// @param _dragoId Id number of the pool /// @param _owner Address of the pool owner /// @param _group Address of the group/factory function registerAs( address _drago, string memory _name, string memory _symbol, - uint256 _dragoId, address _owner, address _group) internal - returns (bool) + returns (uint256) { Drago storage pool = dragos.push(); pool.drago = _drago; - pool.name = _name; - pool.symbol = _symbol; - pool.dragoId = _dragoId; + pool.name = bytes32(bytes(_name)); + pool.symbol = bytes32(bytes(_symbol)); + pool.dragoId = dragos.length + 1; pool.owner = _owner; pool.group = _group; + // TODO: check whether the both following are needed mapFromAddress[_drago] = dragos.length; - mapFromName[_name] = dragos.length; - emit Registered(_name, _symbol, dragos.length - 1, _drago, _owner, _group); - return true; + mapFromName[bytes32(bytes(_name))] = dragos.length; + emit Registered(pool.name, pool.symbol, dragos.length, _drago, _owner, _group); + unchecked{ return pool.dragoId; } } /// @dev Allows anyone to update the owner in the registry diff --git a/contracts/protocol/interfaces/IDragoRegistry.sol b/contracts/protocol/interfaces/IDragoRegistry.sol index fe312e4e..7ac42d3e 100644 --- a/contracts/protocol/interfaces/IDragoRegistry.sol +++ b/contracts/protocol/interfaces/IDragoRegistry.sol @@ -24,10 +24,17 @@ pragma solidity >=0.7.0 <0.9.0; // solhint-disable-next-line interface IDragoRegistry { + /* + * EVENTS + */ + event Registered(bytes32 name, bytes32 indexed symbol, uint256 id, address drago, address indexed owner, address indexed group); + event Unregistered(bytes32 name, bytes32 indexed symbol, uint256 id); + event MetaChanged(uint256 indexed id, bytes32 indexed key, bytes32 value); + /* * CORE FUNCTIONS */ - function register(address _drago, string calldata _name, string calldata _symbol, uint256 _dragoId, address _owner) external payable returns (bool); + function register(address _drago, string calldata _name, string calldata _symbol, address _owner) external payable returns (uint256 poolId); function unregister(uint256 _id) external; function setMeta(uint256 _id, bytes32 _key, bytes32 _value) external; function addGroup(address _group) external; diff --git a/contracts/protocol/proxies/RigoblockPoolProxyFactory.sol b/contracts/protocol/proxies/RigoblockPoolProxyFactory.sol index db10cfc1..f1e4eed5 100644 --- a/contracts/protocol/proxies/RigoblockPoolProxyFactory.sol +++ b/contracts/protocol/proxies/RigoblockPoolProxyFactory.sol @@ -82,20 +82,19 @@ contract RigoblockPoolProxyFactory is Owned, IRigoblockPoolProxyFactory { whenFeePaid returns (address) { - uint256 regFee = data.registry.getFee(); - uint256 dragoId = data.registry.dragoCount(); - createDragoInternal(_name, _symbol, msg.sender, dragoId); - require( - data.registry.register{ value : regFee} ( - libraryData.newAddress, - _name, - _symbol, - dragoId, - msg.sender - ) == true, - "REGISTRY_POOL_FACTORY_ERROR" - ); - return libraryData.newAddress; + createDragoInternal(_name, _symbol, msg.sender); + try data.registry.register{ value : data.registry.getFee() } ( + libraryData.newAddress, + _name, + _symbol, + msg.sender + ) returns (uint256 poolId) + { + emit DragoCreated(_name, _symbol, libraryData.newAddress, owner, poolId); + return libraryData.newAddress; + } catch Error(string memory) { + revert("REGISTRY_POOL_FACTORY_CREATION_ERROR"); + } } // TODO: this method should be moved to the implementation/beacon, or drago should query dao from factory, not in storage @@ -200,7 +199,7 @@ contract RigoblockPoolProxyFactory is Owned, IRigoblockPoolProxyFactory { return ( dragoDao = data.dragoDao, version = VERSION, - nextDragoId = getNextId() + nextDragoId = nextPoolId() ); } @@ -232,12 +231,11 @@ contract RigoblockPoolProxyFactory is Owned, IRigoblockPoolProxyFactory { /// @param _name String of the name /// @param _symbol String of the symbol /// @param _owner Address of the owner - /// @param _poolId Number of the new drago Id function createDragoInternal( string memory _name, string memory _symbol, - address _owner, - uint256 _poolId) + address _owner + ) internal { require( @@ -247,23 +245,21 @@ contract RigoblockPoolProxyFactory is Owned, IRigoblockPoolProxyFactory { _name, _symbol, _owner, - _poolId, data.authority ) ) != address(0), "PROXY_FACTORY_LIBRARY_DEPLOY_ERROR" ); data.dragos[_owner].push(libraryData.newAddress); - emit DragoCreated(_name, _symbol, libraryData.newAddress, _owner, _poolId); } /// @dev Returns the next Id for a drago /// @return nextDragoId Number of the next Id from the registry - function getNextId() + function nextPoolId() internal view returns (uint256 nextDragoId) { - nextDragoId = data.registry.dragoCount(); + unchecked{ nextDragoId = data.registry.dragoCount() + 1; } } } diff --git a/contracts/protocol/proxies/RigoblockPoolProxyFactoryLibrary.sol b/contracts/protocol/proxies/RigoblockPoolProxyFactoryLibrary.sol index bb56a316..1a5dcbff 100644 --- a/contracts/protocol/proxies/RigoblockPoolProxyFactoryLibrary.sol +++ b/contracts/protocol/proxies/RigoblockPoolProxyFactoryLibrary.sol @@ -30,7 +30,6 @@ library RigoblockPoolProxyFactoryLibrary { struct NewPool { string name; string symbol; - uint256 poolId; address owner; address newAddress; } @@ -38,7 +37,6 @@ library RigoblockPoolProxyFactoryLibrary { /// @dev Allows an approved factory to create new pools /// @param _name String of the name /// @param _symbol String of the symbol - /// @param _poolId Number of Id of the pool from the registry /// @param _authority Address of the respective authority /// @return proxy Instance of a Rigoblock pool function createPool0( @@ -46,7 +44,6 @@ library RigoblockPoolProxyFactoryLibrary { string memory _name, string memory _symbol, address _owner, - uint256 _poolId, address _authority) internal returns (RigoblockPoolProxy proxy) @@ -58,7 +55,6 @@ library RigoblockPoolProxyFactoryLibrary { // TODO: check gas saving in forwarding data as struct self.name = _name, self.symbol = _symbol, - self.poolId = _poolId, self.owner = _owner, _authority ) @@ -71,7 +67,6 @@ library RigoblockPoolProxyFactoryLibrary { string memory _name, string memory _symbol, address _owner, - uint256 _poolId, address _authority ) internal @@ -81,7 +76,6 @@ library RigoblockPoolProxyFactoryLibrary { 0xc9ee5905, // RigoblockPool._initializePool.selector self.name = _name, self.symbol = _symbol, - self.poolId = _poolId, self.owner = _owner, _authority ); diff --git a/src/deploy/deploy_factories.ts b/src/deploy/deploy_factories.ts index 57ccde1b..876b0e87 100644 --- a/src/deploy/deploy_factories.ts +++ b/src/deploy/deploy_factories.ts @@ -17,7 +17,10 @@ const deploy: DeployFunction = async function ( const registry = await deploy("DragoRegistry", { from: deployer, - args: [authority.address], + args: [ + authority.address, + deployer + ], log: true, deterministicDeployment: true, }); diff --git a/src/deploy/deploy_tests_setup.ts b/src/deploy/deploy_tests_setup.ts index 2769c0ae..f6e23654 100644 --- a/src/deploy/deploy_tests_setup.ts +++ b/src/deploy/deploy_tests_setup.ts @@ -38,7 +38,10 @@ const deploy: DeployFunction = async function ( const registry = await deploy("DragoRegistry", { from: deployer, - args: [authority.address], + args: [ + authority.address, + deployer + ], log: true, deterministicDeployment: true, });