Skip to content

Commit

Permalink
feat: separate registry
Browse files Browse the repository at this point in the history
  • Loading branch information
0xShaito authored Oct 13, 2023
1 parent 917370a commit 4f7f83b
Show file tree
Hide file tree
Showing 23 changed files with 694 additions and 493 deletions.
3 changes: 0 additions & 3 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,6 @@ OPTIMISM_RPC=
POLYGON_RPC=
GOERLI_RPC=

# Address of the old factory for a new factory deployment to chain to
OLD_FACTORY=

ETHERSCAN_API_KEY=

DEPLOYER_PRIVATE_KEY=
1 change: 0 additions & 1 deletion .github/CODEOWNERS

This file was deleted.

72 changes: 55 additions & 17 deletions .solhint.json
Original file line number Diff line number Diff line change
@@ -1,28 +1,66 @@
{
"extends": "solhint:recommended",
"plugins": ["defi-wonderland"],
"plugins": [
"defi-wonderland"
],
"rules": {
"compiler-version": ["off"],
"compiler-version": [
"off"
],
"constructor-syntax": "warn",
"quotes": ["error", "single"],
"func-visibility": ["warn", { "ignoreConstructors": true }],
"quotes": [
"error",
"single"
],
"func-visibility": [
"warn",
{
"ignoreConstructors": true
}
],
"not-rely-on-time": "off",
"func-name-mixedcase": "off",
"var-name-mixedcase": "off",
"const-name-snakecase": "off",
"no-inline-assembly": "off",
"no-empty-blocks": "off",
"private-vars-leading-underscore": ["warn", { "strict": false }],
"defi-wonderland/non-state-vars-leading-underscore": ["warn"],
"defi-wonderland/contract-data-order": ["warn"],
"defi-wonderland/enum-name-camelcase": ["warn"],
"defi-wonderland/immutable-name-snakecase": ["warn"],
"defi-wonderland/import-statement-format": ["warn"],
"defi-wonderland/interface-member-order": ["warn"],
"defi-wonderland/interface-starts-with-i": ["warn"],
"defi-wonderland/named-return-values": ["warn"],
"defi-wonderland/struct-name-camelcase": ["warn"],
"defi-wonderland/wonder-var-name-mixedcase": ["warn"],
"avoid-low-level-calls": "off"
"private-vars-leading-underscore": [
"warn",
{
"strict": false
}
],
"defi-wonderland/non-state-vars-leading-underscore": [
"warn"
],
"defi-wonderland/contract-data-order": [
"warn"
],
"defi-wonderland/enum-name-camelcase": [
"warn"
],
"defi-wonderland/immutable-name-snakecase": [
"warn"
],
"defi-wonderland/import-statement-format": [
"warn"
],
"defi-wonderland/interface-member-order": [
"warn"
],
"defi-wonderland/interface-starts-with-i": [
"warn"
],
"defi-wonderland/named-return-values": [
"warn"
],
"defi-wonderland/struct-name-camelcase": [
"warn"
],
"defi-wonderland/wonder-var-name-mixedcase": [
"warn"
],
"avoid-low-level-calls": "off",
"func-named-parameters": "off"
}
}
}
23 changes: 23 additions & 0 deletions .solhint.tests.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"extends": "solhint:recommended",
"rules": {
"compiler-version": ["off"],
"constructor-syntax": "warn",
"quotes": ["error", "single"],
"func-visibility": ["warn", { "ignoreConstructors": true }],
"not-rely-on-time": "off",
"func-name-mixedcase": "off",
"const-name-snakecase": "off",
"no-inline-assembly": "off",
"no-empty-blocks": "off",
"state-visibility": "off",
"private-vars-leading-underscore": ["off"],
"reentrancy": "off",
"max-states-count": "off",
"no-global-import": ["off"],
"func-named-parameters": "off",
"no-console": "off",
"event-name-camelcase": "off"
}
}

4 changes: 4 additions & 0 deletions .solhintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
node_modules
cache
out
solidity/scripts
2 changes: 1 addition & 1 deletion foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ multiline_func_header = 'params_first'
fs_permissions = [{ access = "read-write", path = "./"}]

[profile.default]
solc = '0.8.17'
solc = '0.8.18'
src = 'solidity'
test = 'solidity/test'
out = 'out'
Expand Down
12 changes: 6 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@
"postinstall": "forge install",
"lint:check": "yarn lint:sol-tests && yarn lint:sol-logic && forge fmt check",
"lint:fix": "sort-package-json && forge fmt && yarn lint:sol-tests --fix && yarn lint:sol-logic --fix",
"lint:sol-logic": "cross-env solhint -c .solhint.json 'solidity/contracts/**/*.sol' 'solidity/interfaces/**/*.sol'",
"lint:sol-tests": "cross-env solhint 'solidity/test/**/*.sol'",
"lint:sol-logic": "solhint 'solidity/contracts/**/*.sol' 'solidity/interfaces/**/*.sol'",
"lint:sol-tests": "solhint -c .solhint.tests.json 'solidity/test/**/*.sol'",
"prepare": "husky install",
"script:DeployFactory": "forge script solidity/scripts/MultichainDeploy.sol:MultichainDeploy --legacy",
"script:DeployFactory:broadcast": "forge script solidity/scripts/MultichainDeploy.sol:MultichainDeploy --legacy --broadcast --verify --slow",
Expand All @@ -38,17 +38,17 @@
},
"lint-staged": {
"*.{js,css,md,ts,sol}": "forge fmt",
"*.sol": "cross-env solhint --fix 'solidity/**/*.sol",
"*.sol": "solhint --fix 'solidity/**/*.sol'",
"package.json": "sort-package-json"
},
"devDependencies": {
"@commitlint/cli": "17.0.3",
"@commitlint/config-conventional": "17.0.3",
"cross-env": "7.0.3",
"husky": ">=8",
"lint-staged": ">=10",
"solhint": "3.3.6",
"lint-staged": "13.2.2",
"solhint": "3.5.1",
"solhint-plugin-defi-wonderland": "1.1.0",
"sort-package-json": "1.53.1"
}
}
}
152 changes: 1 addition & 151 deletions solidity/contracts/XERC20Factory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,6 @@ import {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet
contract XERC20Factory is IXERC20Factory {
using EnumerableSet for EnumerableSet.AddressSet;

/**
* @notice The version of the factory
* @dev Will revert if version is V0
*/
string public constant VERSION = 'V1';

/**
* @notice The address of the old factory
*/
XERC20Factory public immutable OLD_FACTORY;

/**
* @notice Address of the xerc20 maps to the address of its lockbox if it has one
*/
Expand All @@ -36,10 +25,6 @@ contract XERC20Factory is IXERC20Factory {
*/
EnumerableSet.AddressSet internal _xerc20RegistryArray;

constructor(address _oldFactory) {
OLD_FACTORY = XERC20Factory(_oldFactory);
}

/**
* @notice Deploys an XERC20 contract using CREATE3
* @dev _limits and _minters must be the same length
Expand Down Expand Up @@ -78,148 +63,13 @@ contract XERC20Factory is IXERC20Factory {
if (_baseToken == address(0) && !_isNative) revert IXERC20Factory_BadTokenAddress();

if (XERC20(_xerc20).owner() != msg.sender) revert IXERC20Factory_NotOwner();
if (_getLockboxForXERC20(_xerc20) != address(0)) revert IXERC20Factory_LockboxAlreadyDeployed();
if (_lockboxRegistry[_xerc20] != address(0)) revert IXERC20Factory_LockboxAlreadyDeployed();

_lockbox = _deployLockbox(_xerc20, _baseToken, _isNative);

emit LockboxDeployed(_lockbox);
}

/**
* @notice Loops through the xerc20RegistryArray
*
* @param _start The start of the loop
* @param _amount The end of the loop
* @return _lockboxes The array of xerc20s from the start to start + amount
*/

function getRegisteredLockboxes(uint256 _start, uint256 _amount) public view returns (address[] memory _lockboxes) {
_lockboxes = _getRegisteredSet(_start, _amount, _lockboxRegistryArray);
}

/**
* @notice Loops through the xerc20RegistryArray
*
* @param _start The start of the loop
* @param _amount The amount of xerc20s to loop through
* @return _xerc20s The array of xerc20s from the start to start + amount
*/

function getRegisteredXERC20(uint256 _start, uint256 _amount) public view returns (address[] memory _xerc20s) {
_xerc20s = _getRegisteredSet(_start, _amount, _xerc20RegistryArray);
}

/**
* @notice Returns if an XERC20 is registered
*
* @param _xerc20 The address of the XERC20
* @return _result If the XERC20 is registered
*/

function isRegisteredXERC20(address _xerc20) external view returns (bool _result) {
_result = _isRegisteredXERC20(_xerc20);
}

/**
* @notice Returns if a lockbox is registered
*
* @param _lockbox The address of the lockbox
* @return _result If the lockbox is registered
*/

function isRegisteredLockbox(address _lockbox) external view returns (bool _result) {
_result = _isRegisteredLockbox(_lockbox);
}

/**
* @notice Gets the lockbox that is registered to an XERC20
*
* @param _xerc20 The address of the XERC20
* @return _lockbox The address of the lockbox
*/

function lockboxRegistry(address _xerc20) external view returns (address _lockbox) {
_lockbox = _getLockboxForXERC20(_xerc20);
}

/**
* @notice Gets the lockbox that is registered to an XERC20
*
* @param _xerc20 The address of the XERC20
* @return _lockbox The address of the lockbox
*/

function _getLockboxForXERC20(address _xerc20) internal view returns (address _lockbox) {
_lockbox = _lockboxRegistry[_xerc20];
if (_lockbox == address(0) && address(OLD_FACTORY) != address(0)) {
_lockbox = OLD_FACTORY.lockboxRegistry(_xerc20);
}
}

/**
* @notice Returns if an XERC20 is in a registry
*
* @param _xerc20 The address of the XERC20
* @return _result If the XERC20 is in the registry
*/

function _isRegisteredXERC20(address _xerc20) internal view returns (bool _result) {
_result = EnumerableSet.contains(_xerc20RegistryArray, _xerc20)
|| (address(OLD_FACTORY) != address(0) && OLD_FACTORY.isRegisteredXERC20(_xerc20));
}

/**
* @notice Returns if an lockbox is in a registry
*
* @param _lockbox The address of the lockbox
* @return _result If the lockbox is in the registry
*/

function _isRegisteredLockbox(address _lockbox) internal view returns (bool _result) {
if (EnumerableSet.contains(_lockboxRegistryArray, _lockbox)) {
_result = true;
} else if (address(OLD_FACTORY) != address(0)) {
try OLD_FACTORY.isRegisteredLockbox(_lockbox) returns (bool _isRegistered) {
_result = _isRegistered;
} catch {
// If the function fails then we are going to the first factory where the function does not exist
// Get the xerc20 of the lockbox and check in the old factory if there is a lockbox registered to it
address _xerc20 = address(XERC20Lockbox(payable(_lockbox)).XERC20());

_result = OLD_FACTORY.lockboxRegistry(_xerc20) == _lockbox;
}
}
}

/**
* @notice Loops through an EnumerableSet
*
* @param _start The start of the loop
* @param _amount The amount of indexes to loop through
* @return _result All the values from start to start + amount
*/

function _getRegisteredSet(
uint256 _start,
uint256 _amount,
EnumerableSet.AddressSet storage _set
) internal view returns (address[] memory _result) {
uint256 _length = EnumerableSet.length(_set);
if (_amount > _length - _start) {
_amount = _length - _start;
}

_result = new address[](_amount);
uint256 _index;
while (_index < _amount) {
_result[_index] = EnumerableSet.at(_set, _start + _index);

unchecked {
++_index;
}
}
}

/**
* @notice Deploys an XERC20 contract using CREATE3
* @dev _limits and _minters must be the same length
Expand Down
Loading

0 comments on commit 4f7f83b

Please sign in to comment.