diff --git a/.eslintrc b/.eslintrc index aedef8110..43aa16d92 100644 --- a/.eslintrc +++ b/.eslintrc @@ -26,7 +26,7 @@ "rules": { "prettier/prettier": "error", - "max-len": ["warn", { "code": 140, "ignoreUrls": true }], + "max-len": ["warn", { "code": 140, "ignoreComments": true, "ignoreUrls": true }], "no-undef": "warn", "no-unused-vars": "warn", "prefer-const": "warn", diff --git a/.solhint.json b/.solhint.json new file mode 100644 index 000000000..9a11067d4 --- /dev/null +++ b/.solhint.json @@ -0,0 +1,11 @@ +{ + "extends": "solhint:recommended", + "rules": { + "no-inline-assembly": "off", + "var-name-mixedcase": "off", + "compiler-version": "off", + "reason-string": "off", + "no-empty-blocks": "off", + "func-name-mixedcase": "off" + } +} diff --git a/.soliumrc.json b/.soliumrc.json index 0325d94dc..bd45f50f1 100644 --- a/.soliumrc.json +++ b/.soliumrc.json @@ -1,20 +1,41 @@ { - "extends": "solium:recommended", - "plugins": [ - "security" - ], + "extends": "solium:all", + "plugins": ["security"], "rules": { - "quotes": [ + "security/no-low-level-calls": "off", + "security/no-inline-assembly": "off", + "security/no-assign-params": "warning", + "error-reason": "off", + "imports-on-top": "error", + "variable-declarations": "error", + "array-declarations": "error", + "operator-whitespace": "error", + "conditionals-whitespace": "error", + "comma-whitespace": "error", + "semicolon-whitespace": "error", + "function-whitespace": "error", + "lbrace": "error", + "mixedcase": "off", + "camelcase": "error", + "uppercase": "error", + "no-empty-blocks": "error", + "no-unused-vars": "error", + "quotes": "error", + "blank-lines": "error", + "indentation": "error", + "arg-overflow": ["error", 8], + "whitespace": "error", + "deprecated-suicide": "error", + "pragma-on-top": "error", + "function-order": [ "error", - "double" + {"ignore": {"functions": ["initialize"]}} ], - "indentation": [ - "error", - 4 - ], - "linebreak-style": [ - "error", - "unix" - ] + "emit": "error", + "no-constant": "error", + "value-in-payable": "error", + "max-len": "error", + "visibility-first": "error", + "linebreak-style": "error" } } diff --git a/contracts/0.4.24/DePool.sol b/contracts/0.4.24/DePool.sol index 90f4d7400..3ed441b08 100644 --- a/contracts/0.4.24/DePool.sol +++ b/contracts/0.4.24/DePool.sol @@ -85,9 +85,13 @@ contract DePool is IDePool, IsContract, Pausable, AragonApp { uint256 initialUsedSigningKeys; // for write-back control } - - function initialize(ISTETH _token, IValidatorRegistration validatorRegistration, address _oracle, - IStakingProvidersRegistry _sps, uint256 _depositIterationLimit) + function initialize( + ISTETH _token, + IValidatorRegistration validatorRegistration, + address _oracle, + IStakingProvidersRegistry _sps, + uint256 _depositIterationLimit + ) public onlyInit { _setToken(_token); @@ -99,7 +103,6 @@ contract DePool is IDePool, IsContract, Pausable, AragonApp { initialized(); } - /** * @notice Adds eth to the pool */ @@ -115,7 +118,6 @@ contract DePool is IDePool, IsContract, Pausable, AragonApp { return _submit(_referral); } - /** * @notice Stop pool routine operations */ @@ -130,7 +132,6 @@ contract DePool is IDePool, IsContract, Pausable, AragonApp { _resume(); } - /** * @notice Set fee rate to `_feeBasisPoints` basis points. The fees are accrued when oracles report staking results * @param _feeBasisPoints Fee rate, in basis points @@ -143,11 +144,19 @@ contract DePool is IDePool, IsContract, Pausable, AragonApp { /** * @notice Set fee distribution: `_treasuryFeeBasisPoints` basis points go to the treasury, `_insuranceFeeBasisPoints` basis points go to the insurance fund, `_SPFeeBasisPoints` basis points go to staking providers. The sum has to be 10 000. */ - function setFeeDistribution(uint16 _treasuryFeeBasisPoints, uint16 _insuranceFeeBasisPoints, - uint16 _SPFeeBasisPoints) external auth(MANAGE_FEE) + function setFeeDistribution( + uint16 _treasuryFeeBasisPoints, + uint16 _insuranceFeeBasisPoints, + uint16 _SPFeeBasisPoints + ) + external auth(MANAGE_FEE) { - require(10000 == uint256(_treasuryFeeBasisPoints).add(uint256(_insuranceFeeBasisPoints)).add(uint256(_SPFeeBasisPoints)), - "FEES_DONT_ADD_UP"); + require( + 10000 == uint256(_treasuryFeeBasisPoints) + .add(uint256(_insuranceFeeBasisPoints)) + .add(uint256(_SPFeeBasisPoints)), + "FEES_DONT_ADD_UP" + ); _setBPValue(TREASURY_FEE_VALUE_POSITION, _treasuryFeeBasisPoints); _setBPValue(INSURANCE_FEE_VALUE_POSITION, _insuranceFeeBasisPoints); @@ -164,7 +173,6 @@ contract DePool is IDePool, IsContract, Pausable, AragonApp { _setOracle(_oracle); } - /** * @notice Set maximum number of Ethereum 2.0 validators registered in a single transaction. */ @@ -172,7 +180,6 @@ contract DePool is IDePool, IsContract, Pausable, AragonApp { _setDepositIterationLimit(_limit); } - /** * @notice Set credentials to withdraw ETH on ETH 2.0 side after the phase 2 is launched to `_withdrawalCredentials` * @dev Note that setWithdrawalCredentials discards all unused signing keys as the signatures are invalidated. @@ -188,17 +195,15 @@ contract DePool is IDePool, IsContract, Pausable, AragonApp { emit WithdrawalCredentialsSet(_withdrawalCredentials); } - /** * @notice Issues withdrawal request. Large withdrawals will be processed only after the phase 2 launch. WIP. * @param _amount Amount of StETH to burn * @param _pubkeyHash Receiving address */ - function withdraw(uint256 _amount, bytes32 _pubkeyHash) external whenNotStopped { + function withdraw(uint256 _amount, bytes32 _pubkeyHash) external whenNotStopped { /* solhint-disable-line no-unused-vars */ revert("NOT_IMPLEMENTED_YET"); } - /** * @notice Ether on the ETH 2.0 side reported by the oracle * @param _eth2balance Balance in wei on the ETH 2.0 side @@ -222,11 +227,10 @@ contract DePool is IDePool, IsContract, Pausable, AragonApp { } } - /** - * @notice Send funds to recovery Vault. Overrides default AragonApp behaviour. - * @param _token Token to be sent to recovery vault. - */ + * @notice Send funds to recovery Vault. Overrides default AragonApp behaviour. + * @param _token Token to be sent to recovery vault. + */ function transferToVault(address _token) external { require(allowRecoverability(_token), "RECOVER_DISALLOWED"); address vault = getRecoveryVault(); @@ -245,7 +249,6 @@ contract DePool is IDePool, IsContract, Pausable, AragonApp { emit RecoverToVault(vault, _token, balance); } - /** * @notice Returns staking rewards fee rate */ @@ -256,8 +259,14 @@ contract DePool is IDePool, IsContract, Pausable, AragonApp { /** * @notice Returns fee distribution proportion */ - function getFeeDistribution() external view returns (uint16 treasuryFeeBasisPoints, uint16 insuranceFeeBasisPoints, - uint16 SPFeeBasisPoints) + function getFeeDistribution() + external + view + returns ( + uint16 treasuryFeeBasisPoints, + uint16 insuranceFeeBasisPoints, + uint16 SPFeeBasisPoints + ) { return _getFeeDistribution(); } @@ -269,7 +278,6 @@ contract DePool is IDePool, IsContract, Pausable, AragonApp { return withdrawalCredentials; } - /** * @notice Gets the amount of Ether temporary buffered on this contract balance */ @@ -284,7 +292,6 @@ contract DePool is IDePool, IsContract, Pausable, AragonApp { return _getTotalControlledEther(); } - /** * @notice Gets liquid token interface handle */ @@ -314,9 +321,9 @@ contract DePool is IDePool, IsContract, Pausable, AragonApp { } /** - * @notice Returns the value against which the next reward will be calculated - * This method can be discarded in the future - */ + * @notice Returns the value against which the next reward will be calculated + * This method can be discarded in the future + */ function getRewardBase() public view returns (uint256) { return REWARD_BASE_VALUE_POSITION.getStorageUint256(); } @@ -350,12 +357,11 @@ contract DePool is IDePool, IsContract, Pausable, AragonApp { * @return deposited Amount of Ether deposited from the current Ethereum * @return remote Amount of Ether currently present on the Ethereum 2 side (can be 0 if the Ethereum 2 is yet to be launch */ - function getEther2Stat() external view returns (uint256 deposited, uint256 remote) { + function getEther2Stat() public view returns (uint256 deposited, uint256 remote) { deposited = DEPOSITED_ETHER_VALUE_POSITION.getStorageUint256(); remote = REMOTE_ETHER2_VALUE_POSITION.getStorageUint256(); } - /** * @dev Sets liquid token interface handle */ @@ -396,7 +402,6 @@ contract DePool is IDePool, IsContract, Pausable, AragonApp { DEPOSIT_ITERATION_LIMIT_VALUE_POSITION.setStorageUint256(_limit); } - /** * @dev Processes user deposit */ @@ -440,7 +445,8 @@ contract DePool is IDePool, IsContract, Pausable, AragonApp { uint256 totalDepositCalls = 0; uint256 maxDepositCalls = getDepositIterationLimit(); - while (_amount != 0 && totalDepositCalls < maxDepositCalls) { + uint256 depositAmount = _amount; + while (depositAmount != 0 && totalDepositCalls < maxDepositCalls) { // Finding the best suitable SP uint256 bestSPidx = cache.length; // 'not found' flag uint256 smallestStake; @@ -466,11 +472,11 @@ contract DePool is IDePool, IsContract, Pausable, AragonApp { break; // Invoking deposit for the best SP - _amount = _amount.sub(DEPOSIT_SIZE); + depositAmount = depositAmount.sub(DEPOSIT_SIZE); ++totalDepositCalls; - (bytes memory key, bytes memory signature, bool used) = - getSPs().getSigningKey(cache[bestSPidx].id, cache[bestSPidx].usedSigningKeys++); + (bytes memory key, bytes memory signature, bool used) = /* solium-disable-line */ + getSPs().getSigningKey(cache[bestSPidx].id, cache[bestSPidx].usedSigningKeys++); assert(!used); // finally, stake the notch for the assigned validator @@ -502,15 +508,19 @@ contract DePool is IDePool, IsContract, Pausable, AragonApp { // Compute deposit data root (`DepositData` hash tree root) according to validator_registration.vy bytes32 pubkeyRoot = sha256(_pad64(_pubkey)); - bytes32 signatureRoot = sha256(abi.encodePacked( - sha256(BytesLib.slice(_signature, 0, 64)), - sha256(_pad64(BytesLib.slice(_signature, 64, SIGNATURE_LENGTH.sub(64)))) - )); + bytes32 signatureRoot = sha256( + abi.encodePacked( + sha256(BytesLib.slice(_signature, 0, 64)), + sha256(_pad64(BytesLib.slice(_signature, 64, SIGNATURE_LENGTH.sub(64)))) + ) + ); - bytes32 depositDataRoot = sha256(abi.encodePacked( - sha256(abi.encodePacked(pubkeyRoot, withdrawalCredentials)), - sha256(abi.encodePacked(_toLittleEndian64(depositAmount), signatureRoot)) - )); + bytes32 depositDataRoot = sha256( + abi.encodePacked( + sha256(abi.encodePacked(pubkeyRoot, withdrawalCredentials)), + sha256(abi.encodePacked(_toLittleEndian64(depositAmount), signatureRoot)) + ) + ); uint256 targetBalance = address(this).balance.sub(value); @@ -543,7 +553,6 @@ contract DePool is IDePool, IsContract, Pausable, AragonApp { ); } - /** * @dev Records a deposit made by a user with optional referral * @param _value Deposit value in wei @@ -602,7 +611,6 @@ contract DePool is IDePool, IsContract, Pausable, AragonApp { getSPs().updateUsedKeys(ids, usedSigningKeys); } - /** * @dev Returns staking rewards fee rate */ @@ -698,7 +706,6 @@ contract DePool is IDePool, IsContract, Pausable, AragonApp { require(idx == cache.length, "SP_REGISTRY_INCOSISTENCY"); } - /** * @dev Padding memory array with zeroes up to 64 bytes on the right * @param _b Memory array of size 32 .. 64 @@ -723,12 +730,13 @@ contract DePool is IDePool, IsContract, Pausable, AragonApp { */ function _toLittleEndian64(uint256 _value) internal pure returns (uint256 result) { result = 0; + uint256 temp_value = _value; for (uint256 i = 0; i < 8; ++i) { - result = (result << 8) | (_value & 0xFF); - _value >>= 8; + result = (result << 8) | (temp_value & 0xFF); + temp_value >>= 8; } - assert(0 == _value); // fully converted + assert(0 == temp_value); // fully converted result <<= (24 * 8); } diff --git a/contracts/0.4.24/StETH.sol b/contracts/0.4.24/StETH.sol index cc16356f4..6687e8868 100644 --- a/contracts/0.4.24/StETH.sol +++ b/contracts/0.4.24/StETH.sol @@ -50,6 +50,10 @@ contract StETH is ISTETH, Pausable, AragonApp { uint256 value ); + function initialize(IDePool _dePool) public onlyInit { + dePool = _dePool; + initialized(); + } /** * @notice Stop transfers @@ -101,11 +105,6 @@ contract StETH is ISTETH, Pausable, AragonApp { _burn(_account, _value); } - function initialize(IDePool _dePool) public onlyInit { - dePool = _dePool; - initialized(); - } - /** * @dev Total number of tokens in existence */ diff --git a/contracts/0.4.24/interfaces/IDePool.sol b/contracts/0.4.24/interfaces/IDePool.sol index 028db5524..26d93abf9 100644 --- a/contracts/0.4.24/interfaces/IDePool.sol +++ b/contracts/0.4.24/interfaces/IDePool.sol @@ -34,8 +34,11 @@ interface IDePool { /** * @notice Set fee distribution: `_treasuryFeeBasisPoints` basis points go to the treasury, `_insuranceFeeBasisPoints` basis points go to the insurance fund, `_SPFeeBasisPoints` basis points go to staking providers. The sum has to be 10 000. */ - function setFeeDistribution(uint16 _treasuryFeeBasisPoints, uint16 _insuranceFeeBasisPoints, - uint16 _SPFeeBasisPoints) external; + function setFeeDistribution( + uint16 _treasuryFeeBasisPoints, + uint16 _insuranceFeeBasisPoints, + uint16 _SPFeeBasisPoints) + external; /** * @notice Returns staking rewards fee rate diff --git a/contracts/0.4.24/interfaces/IValidatorRegistration.sol b/contracts/0.4.24/interfaces/IValidatorRegistration.sol index 0316c6813..b75ef1750 100644 --- a/contracts/0.4.24/interfaces/IValidatorRegistration.sol +++ b/contracts/0.4.24/interfaces/IValidatorRegistration.sol @@ -12,8 +12,11 @@ interface IValidatorRegistration { * @param signature Signature of the request * @param deposit_data_root The deposits Merkle tree node, used as a checksum */ - function deposit(bytes /* 48 */ pubkey, - bytes /* 32 */ withdrawal_credentials, - bytes /* 96 */ signature, - bytes32 deposit_data_root) external payable; + function deposit( + bytes /* 48 */ pubkey, + bytes /* 32 */ withdrawal_credentials, + bytes /* 96 */ signature, + bytes32 deposit_data_root + ) + external payable; } diff --git a/contracts/0.4.24/lib/Pausable.sol b/contracts/0.4.24/lib/Pausable.sol index b976bd7a1..9fc5c6406 100644 --- a/contracts/0.4.24/lib/Pausable.sol +++ b/contracts/0.4.24/lib/Pausable.sol @@ -12,7 +12,7 @@ contract Pausable { bytes32 internal constant STOPPED_FLAG_POSITION = keccak256("depools.Pausable.stopped"); modifier whenNotStopped() { - require(!(STOPPED_FLAG_POSITION.getStorageBool()), "CONTRACT_IS_STOPPED"); + require(!STOPPED_FLAG_POSITION.getStorageBool(), "CONTRACT_IS_STOPPED"); _; } @@ -21,6 +21,10 @@ contract Pausable { _; } + function isStopped() external view returns (bool) { + return STOPPED_FLAG_POSITION.getStorageBool(); + } + function _stop() internal whenNotStopped { STOPPED_FLAG_POSITION.setStorageBool(true); emit Stopped(); @@ -30,8 +34,4 @@ contract Pausable { STOPPED_FLAG_POSITION.setStorageBool(false); emit Resumed(); } - - function isStopped() external view returns (bool) { - return STOPPED_FLAG_POSITION.getStorageBool(); - } } diff --git a/contracts/0.4.24/oracle/Algorithm.sol b/contracts/0.4.24/oracle/Algorithm.sol index 0a4a6dec2..a189b4a2d 100644 --- a/contracts/0.4.24/oracle/Algorithm.sol +++ b/contracts/0.4.24/oracle/Algorithm.sol @@ -45,14 +45,16 @@ library Algorithm { // find mode value index uint256 mostFrequentValueIndex = 0; - for (i = 1; i < dataValuesLength; i++) + for (i = 1; i < dataValuesLength; i++) { if (dataValuesCounts[i] > dataValuesCounts[mostFrequentValueIndex]) mostFrequentValueIndex = i; + } // check if data is unimodal - for (i = 0; i < dataValuesLength; i++) + for (i = 0; i < dataValuesLength; i++) { if ((i != mostFrequentValueIndex) && (dataValuesCounts[i] == dataValuesCounts[mostFrequentValueIndex])) return (false, 0); + } return (true, dataValues[mostFrequentValueIndex]); } diff --git a/contracts/0.4.24/oracle/BitOps.sol b/contracts/0.4.24/oracle/BitOps.sol index 23d796feb..d2c50dcef 100644 --- a/contracts/0.4.24/oracle/BitOps.sol +++ b/contracts/0.4.24/oracle/BitOps.sol @@ -25,14 +25,15 @@ library BitOps { */ function popcnt(uint256 _mask) internal pure returns (uint256) { uint256 result = 0; + uint256 tmp_mask = _mask; for (uint256 i = 0; i < 256; ++i) { - if (1 == _mask & 1) { + if (1 == tmp_mask & 1) { result++; } - _mask >>= 1; + tmp_mask >>= 1; } - assert(0 == _mask); + assert(0 == tmp_mask); return result; } } diff --git a/contracts/0.4.24/oracle/DePoolOracle.sol b/contracts/0.4.24/oracle/DePoolOracle.sol index 7c039aeab..a24c7d9bc 100644 --- a/contracts/0.4.24/oracle/DePoolOracle.sol +++ b/contracts/0.4.24/oracle/DePoolOracle.sol @@ -11,6 +11,7 @@ import "../interfaces/IDePool.sol"; import "./Algorithm.sol"; import "./BitOps.sol"; + /** * @title Implementation of an ETH 2.0 -> ETH oracle * @@ -57,14 +58,11 @@ contract DePoolOracle is IDePoolOracle, IsContract, AragonApp { uint256 private contributionBitMask; uint256[] private currentlyAggregatedData; // only indexes set in contributionBitMask are valid - function initialize() public onlyInit { assert(1 == ((1 << (MAX_MEMBERS - 1)) >> (MAX_MEMBERS - 1))); // static assert - initialized(); } - /** * @notice Set the pool address to `_pool` */ @@ -136,7 +134,6 @@ contract DePoolOracle is IDePoolOracle, IsContract, AragonApp { _assertInvariants(); } - /** * @notice An oracle committee member pushes data from the ETH 2.0 side * @param _reportInterval ReportInterval id @@ -170,7 +167,6 @@ contract DePoolOracle is IDePoolOracle, IsContract, AragonApp { _tryFinalize(_reportInterval); } - /** * @notice Returns the current oracle member committee */ @@ -185,7 +181,6 @@ contract DePoolOracle is IDePoolOracle, IsContract, AragonApp { return quorum; } - /** * @notice Returns reportInterval duration in seconds * @dev ReportIntervals are consecutive time intervals. Oracle data is aggregated @@ -210,7 +205,6 @@ contract DePoolOracle is IDePoolOracle, IsContract, AragonApp { return _getCurrentReportInterval(); } - /** * @notice Returns the latest data from the ETH 2.0 side * @dev Depending on the oracle member committee liveness, the data can be stale. See _reportInterval. @@ -221,7 +215,6 @@ contract DePoolOracle is IDePoolOracle, IsContract, AragonApp { return (lastFinalizedReportInterval, lastFinalizedData); } - /** * @dev Finalizes the current data point if quorum is reached */ @@ -262,14 +255,6 @@ contract DePoolOracle is IDePoolOracle, IsContract, AragonApp { pool.reportEther2(lastFinalizedReportInterval, lastFinalizedData); } - /** - * @dev Checks code self-consistency - */ - function _assertInvariants() private view { - assert(quorum != 0 && members.length >= quorum); - assert(members.length <= MAX_MEMBERS); - } - /** * @dev Returns member's index in the members array or MEMBER_NOT_FOUND */ @@ -284,7 +269,6 @@ contract DePoolOracle is IDePoolOracle, IsContract, AragonApp { return MEMBER_NOT_FOUND; } - /** * @dev Returns current timestamp */ @@ -306,4 +290,12 @@ contract DePoolOracle is IDePoolOracle, IsContract, AragonApp { function _getReportIntervalForTimestamp(uint256 _timestamp) internal pure returns (uint256) { return _timestamp.div(REPORT_INTERVAL_DURATION); } + + /** + * @dev Checks code self-consistency + */ + function _assertInvariants() private view { + assert(quorum != 0 && members.length >= quorum); + assert(members.length <= MAX_MEMBERS); + } } diff --git a/contracts/0.4.24/oracle/test_helpers/TestAlgorithm.sol b/contracts/0.4.24/oracle/test_helpers/TestAlgorithm.sol index 61c5577de..3743a9777 100644 --- a/contracts/0.4.24/oracle/test_helpers/TestAlgorithm.sol +++ b/contracts/0.4.24/oracle/test_helpers/TestAlgorithm.sol @@ -2,6 +2,7 @@ pragma solidity 0.4.24; import "../Algorithm.sol"; + contract TestAlgorithm { function modeTest(uint256[] data) public pure returns (bool isUnimodal, uint256 mode) { return Algorithm.mode(data); diff --git a/contracts/0.4.24/sps/StakingProvidersRegistry.sol b/contracts/0.4.24/sps/StakingProvidersRegistry.sol index 606b7ec24..d2f6a1720 100644 --- a/contracts/0.4.24/sps/StakingProvidersRegistry.sol +++ b/contracts/0.4.24/sps/StakingProvidersRegistry.sol @@ -79,14 +79,12 @@ contract StakingProvidersRegistry is IStakingProvidersRegistry, IsContract, Arag _; } - function initialize() public onlyInit { totalSPCount = 0; activeSPCount = 0; initialized(); } - /** * @notice Set the pool address to `_pool` */ @@ -95,7 +93,6 @@ contract StakingProvidersRegistry is IStakingProvidersRegistry, IsContract, Arag pool = _pool; } - /** * @notice Add staking provider named `name` with reward address `rewardAddress` and staking limit `stakingLimit` validators * @param _name Human-readable name @@ -219,9 +216,8 @@ contract StakingProvidersRegistry is IStakingProvidersRegistry, IsContract, Arag function trimUnusedKeys() external onlyPool { uint256 length = totalSPCount; for (uint256 SP_id = 0; SP_id < length; ++SP_id) { - if (sps[SP_id].totalSigningKeys != sps[SP_id].usedSigningKeys) // write only if update is needed - // discard unused keys - sps[SP_id].totalSigningKeys = sps[SP_id].usedSigningKeys; + if (sps[SP_id].totalSigningKeys != sps[SP_id].usedSigningKeys) // write only if update is needed + sps[SP_id].totalSigningKeys = sps[SP_id].usedSigningKeys; // discard unused keys } } @@ -253,7 +249,13 @@ contract StakingProvidersRegistry is IStakingProvidersRegistry, IsContract, Arag * @param _pubkeys Several concatenated validator signing keys * @param _signatures Several concatenated signatures for (pubkey, withdrawal_credentials, 32000000000) messages */ - function addSigningKeysSP(uint256 _SP_id, uint256 _quantity, bytes _pubkeys, bytes _signatures) external + function addSigningKeysSP( + uint256 _SP_id, + uint256 _quantity, + bytes _pubkeys, + bytes _signatures + ) + external { require(msg.sender == sps[_SP_id].rewardAddress, "APP_AUTH_FAILED"); _addSigningKeys(_SP_id, _quantity, _pubkeys, _signatures); @@ -264,7 +266,8 @@ contract StakingProvidersRegistry is IStakingProvidersRegistry, IsContract, Arag * @param _SP_id Staking provider id * @param _index Index of the key, starting with 0 */ - function removeSigningKey(uint256 _SP_id, uint256 _index) external + function removeSigningKey(uint256 _SP_id, uint256 _index) + external authP(MANAGE_SIGNING_KEYS, arr(_SP_id)) { _removeSigningKey(_SP_id, _index); @@ -275,8 +278,7 @@ contract StakingProvidersRegistry is IStakingProvidersRegistry, IsContract, Arag * @param _SP_id Staking provider id * @param _index Index of the key, starting with 0 */ - function removeSigningKeySP(uint256 _SP_id, uint256 _index) external - { + function removeSigningKeySP(uint256 _SP_id, uint256 _index) external { require(msg.sender == sps[_SP_id].rewardAddress, "APP_AUTH_FAILED"); _removeSigningKey(_SP_id, _index); } @@ -313,13 +315,13 @@ contract StakingProvidersRegistry is IStakingProvidersRegistry, IsContract, Arag } } - /** * @notice Returns total number of staking providers */ function getStakingProvidersCount() external view returns (uint256) { return totalSPCount; } + /** * @notice Returns number of active staking providers */ @@ -389,7 +391,6 @@ contract StakingProvidersRegistry is IStakingProvidersRegistry, IsContract, Arag return (key_, signature, _index < sps[_SP_id].usedSigningKeys); } - function _isEmptySigningKey(bytes memory _key) internal pure returns (bool) { assert(_key.length == PUBKEY_LENGTH); // algorithm applicability constraint diff --git a/contracts/0.4.24/sps/test_helpers/TestStakingProvidersRegistry.sol b/contracts/0.4.24/sps/test_helpers/TestStakingProvidersRegistry.sol index af578d9a8..b2381a06f 100644 --- a/contracts/0.4.24/sps/test_helpers/TestStakingProvidersRegistry.sol +++ b/contracts/0.4.24/sps/test_helpers/TestStakingProvidersRegistry.sol @@ -6,5 +6,4 @@ import "../StakingProvidersRegistry.sol"; /** * @dev Only for testing purposes! StakingProvidersRegistry version with some functions exposed. */ -contract TestStakingProvidersRegistry is StakingProvidersRegistry { -} +contract TestStakingProvidersRegistry is StakingProvidersRegistry {} /* solium-disable-line no-empty-blocks */ diff --git a/contracts/0.4.24/template/DePoolTemplate.sol b/contracts/0.4.24/template/DePoolTemplate.sol index 1ce6e81ec..ae20ce950 100644 --- a/contracts/0.4.24/template/DePoolTemplate.sol +++ b/contracts/0.4.24/template/DePoolTemplate.sol @@ -45,9 +45,14 @@ contract DePoolTemplate is BaseTemplate { DePool private depool; - constructor(DAOFactory _daoFactory, ENS _ens, MiniMeTokenFactory _miniMeFactory, IFIFSResolvingRegistrar _aragonID) - BaseTemplate(_daoFactory, _ens, _miniMeFactory, _aragonID) + constructor( + DAOFactory _daoFactory, + ENS _ens, + MiniMeTokenFactory _miniMeFactory, + IFIFSResolvingRegistrar _aragonID + ) public + BaseTemplate(_daoFactory, _ens, _miniMeFactory, _aragonID) { _ensureAragonIdIsValid(_aragonID); _ensureMiniMeFactoryIsValid(_miniMeFactory); @@ -115,9 +120,14 @@ contract DePoolTemplate is BaseTemplate { initializeData = abi.encodeWithSelector(StakingProvidersRegistry(0).initialize.selector); sps = StakingProvidersRegistry(_installNonDefaultApp(dao, REGISTRY_APP_ID, initializeData)); - initializeData = abi.encodeWithSelector(DePool(0).initialize.selector, - steth, _ETH2ValidatorRegistrationContract, - oracle, sps, _depositIterationLimit); + initializeData = abi.encodeWithSelector( + DePool(0).initialize.selector, + steth, + _ETH2ValidatorRegistrationContract, + oracle, + sps, + _depositIterationLimit + ); depool = DePool(_installNonDefaultApp(dao, DEPOOL_APP_ID, initializeData)); } diff --git a/contracts/0.4.24/template/Imports.sol b/contracts/0.4.24/template/Imports.sol index 30c43617b..67e4ff0b8 100644 --- a/contracts/0.4.24/template/Imports.sol +++ b/contracts/0.4.24/template/Imports.sol @@ -13,6 +13,5 @@ import "@aragon/os/contracts/lib/ens/AbstractENS.sol"; import "@aragon/os/contracts/lib/ens/PublicResolver.sol"; import "@aragon/id/contracts/FIFSResolvingRegistrar.sol"; -contract Imports { - // solium-disable-previous-line no-empty-blocks -} \ No newline at end of file + +contract Imports {} /* solium-disable-line no-empty-blocks */ diff --git a/contracts/0.4.24/test_helpers/TestDePool.sol b/contracts/0.4.24/test_helpers/TestDePool.sol index fbce85db0..863b5b564 100644 --- a/contracts/0.4.24/test_helpers/TestDePool.sol +++ b/contracts/0.4.24/test_helpers/TestDePool.sol @@ -11,8 +11,13 @@ contract TestDePool is DePool { address private treasury; address private insurance; - function initialize(ISTETH _token, IValidatorRegistration validatorRegistration, address _oracle, - IStakingProvidersRegistry _sps, uint256 _depositIterationLimit) + function initialize( + ISTETH _token, + IValidatorRegistration validatorRegistration, + address _oracle, + IStakingProvidersRegistry _sps, + uint256 _depositIterationLimit + ) public { super.initialize(_token, validatorRegistration, _oracle, _sps, _depositIterationLimit); diff --git a/contracts/0.4.24/test_helpers/ValidatorRegistrationMock.sol b/contracts/0.4.24/test_helpers/ValidatorRegistrationMock.sol index e8c0e679a..ad766bd96 100644 --- a/contracts/0.4.24/test_helpers/ValidatorRegistrationMock.sol +++ b/contracts/0.4.24/test_helpers/ValidatorRegistrationMock.sol @@ -17,11 +17,12 @@ contract ValidatorRegistrationMock is IValidatorRegistration { Call[] public calls; - - function deposit(bytes /* 48 */ pubkey, - bytes /* 32 */ withdrawal_credentials, - bytes /* 96 */ signature, - bytes32 deposit_data_root) + function deposit( + bytes /* 48 */ pubkey, + bytes /* 32 */ withdrawal_credentials, + bytes /* 96 */ signature, + bytes32 deposit_data_root + ) external payable { diff --git a/contracts/0.6.12/CstETH.sol b/contracts/0.6.12/CstETH.sol index aaa8c8452..9c14cbcc9 100644 --- a/contracts/0.6.12/CstETH.sol +++ b/contracts/0.6.12/CstETH.sol @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: NONE /* See contracts/COMPILERS.md */ pragma solidity 0.6.12; @@ -5,7 +6,8 @@ import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import "@openzeppelin/contracts/token/ERC20/ERC20Burnable.sol"; import "@openzeppelin/contracts/token/ERC20/SafeERC20.sol"; import "@openzeppelin/contracts/math/SafeMath.sol"; -import "./IStETH.sol"; +import "./interfaces/IStETH.sol"; + /** * @title Token wrapper of stETH with static balances. diff --git a/contracts/0.6.12/IStETH.sol b/contracts/0.6.12/interfaces/IStETH.sol similarity index 90% rename from contracts/0.6.12/IStETH.sol rename to contracts/0.6.12/interfaces/IStETH.sol index 9f098ecfe..99b525b3e 100644 --- a/contracts/0.6.12/IStETH.sol +++ b/contracts/0.6.12/interfaces/IStETH.sol @@ -1,7 +1,10 @@ +// SPDX-License-Identifier: NONE + pragma solidity 0.6.12; // latest available for using OZ import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; + interface IStETH is IERC20 { function getPooledEthByShares(uint256 _sharesAmount) external view returns (uint256); diff --git a/contracts/0.6.12/mocks/CstETHMock.sol b/contracts/0.6.12/mocks/CstETHMock.sol index 5189074bd..68396c2e4 100644 --- a/contracts/0.6.12/mocks/CstETHMock.sol +++ b/contracts/0.6.12/mocks/CstETHMock.sol @@ -1,13 +1,13 @@ +// SPDX-License-Identifier: NONE + pragma solidity 0.6.12; // latest available for using OZ import "../CstETH.sol"; -import "../IStETH.sol"; +import "../interfaces/IStETH.sol"; + contract CstETHMock is CstETH { - constructor(IStETH _stETH) - public - CstETH(_stETH) - { } + constructor(IStETH _stETH) public CstETH(_stETH) {} function mint(address recipient, uint256 amount) public { _mint(recipient, amount); diff --git a/contracts/0.6.12/mocks/StETHMock.sol b/contracts/0.6.12/mocks/StETHMock.sol index 7b2c90fd7..8fd75409d 100644 --- a/contracts/0.6.12/mocks/StETHMock.sol +++ b/contracts/0.6.12/mocks/StETHMock.sol @@ -1,8 +1,11 @@ +// SPDX-License-Identifier: NONE + pragma solidity 0.6.12; // latest available for using OZ import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import "@openzeppelin/contracts/token/ERC20/ERC20Burnable.sol"; + contract StETHMock is ERC20, ERC20Burnable { constructor() public ERC20("Liquid staked DePool Ether", "StETH") {} diff --git a/package.json b/package.json index c79b72c2c..d87ddb35d 100644 --- a/package.json +++ b/package.json @@ -6,10 +6,14 @@ "apps/*/app" ], "scripts": { - "lint": "yarn run lint:sol && yarn run lint:js", - "lint:sol": "solium --dir ./contracts", + "lint": "yarn lint:sol && yarn lint:js", + "lint:sol": "yarn lint:sol:solhint && yarn lint:sol:solium", "lint:js": "eslint --ext .js --cache --ignore-path .gitignore .", "lint:js:fix": "eslint --fix --ext .js --cache --ignore-path .gitignore .", + "lint:sol:solium": "solium --dir ./contracts", + "lint:sol:solium:fix": "solium --dir ./contracts --fix", + "lint:sol:solhint": "solhint \"contracts/**/*.sol\"", + "lint:sol:solhint:fix": "solhint \"contracts/**/*.sol\" --fix", "test": "yarn run test:unit", "test:unit": "yarn run compile:6 && buidler test --network buidlerevm", "test:gas": "yarn run compile:6 && REPORT_GAS=true buidler test --network localhost", @@ -73,6 +77,7 @@ "lerna": "^3.22.1", "lint-staged": ">=10", "prettier": "^2.1.2", + "solhint": "^3.2.2", "solidity-coverage": "^0.7.11", "solium": "^1.2.5", "truffle": "^5.1.43", diff --git a/test/0.4.24/depool.test.js b/test/0.4.24/depool.test.js index a607092bc..df71a93a4 100644 --- a/test/0.4.24/depool.test.js +++ b/test/0.4.24/depool.test.js @@ -1,8 +1,7 @@ -const { join } = require('path') const { assert } = require('chai') const { newDao, newApp } = require('./helpers/dao') -const { assertBn, assertRevert, assertEvent, assertAmountOfEvents } = require('@aragon/contract-helpers-test/src/asserts') -const { ONE_DAY, ZERO_ADDRESS, MAX_UINT64, bn, getEventArgument, injectWeb3, injectArtifacts } = require('@aragon/contract-helpers-test') +const { assertBn, assertRevert, assertEvent } = require('@aragon/contract-helpers-test/src/asserts') +const { ZERO_ADDRESS, bn } = require('@aragon/contract-helpers-test') const { BN } = require('bn.js') const StETH = artifacts.require('StETH.sol') // we can just import due to StETH imported in test_helpers/Imports.sol diff --git a/test/0.4.24/depool_w_steth.test.js b/test/0.4.24/depool_w_steth.test.js index 847afa9e7..fd926218b 100644 --- a/test/0.4.24/depool_w_steth.test.js +++ b/test/0.4.24/depool_w_steth.test.js @@ -1,8 +1,6 @@ -const { join } = require('path') const { assert } = require('chai') const { newDao, newApp } = require('./helpers/dao') -const { assertBn, assertRevert, assertEvent, assertAmountOfEvents } = require('@aragon/contract-helpers-test/src/asserts') -const { ONE_DAY, ZERO_ADDRESS, MAX_UINT64, bn, getEventArgument, injectWeb3, injectArtifacts } = require('@aragon/contract-helpers-test') +const { assertBn } = require('@aragon/contract-helpers-test/src/asserts') const { BN } = require('bn.js') const StETH = artifacts.require('StETH.sol') // we can just import due to StETH imported in test_helpers/Imports.sol @@ -156,7 +154,7 @@ contract('DePool with StEth', ([appManager, voting, user1, user2, user3, nobody, }) it('stETH: totalSupply=34 user2=34', async () => { - /* The initial deposit initiates the stETH token with the corresponding totalSupply + /* The initial deposit initiates the stETH token with the corresponding totalSupply that is taken from dePool.totalControlledEther. Submitter's balance is equivalent to deposited Ether amount. */ @@ -184,7 +182,7 @@ contract('DePool with StEth', ([appManager, voting, user1, user2, user3, nobody, it('DePool: deposited=32, remote=30, buffered=2, totalControlled=32, rewBase=32', async () => { /* The oracle's report changes `remote` value (was 32, became 30). This affects output of totalControlledEther, that decreased by 2. - getRewardBase didn't change. Validators need to compensate the loss occured due to their fault + getRewardBase didn't change. Validators need to compensate the loss occured due to their fault before receiving fees from rewards. */ const stat = await app.getEther2Stat() @@ -224,7 +222,7 @@ contract('DePool with StEth', ([appManager, voting, user1, user2, user3, nobody, totalControlledEther = 34 Ether initial submission + 1 Ether reward = 35 Ether or totalControlledEther = 33 Ether remote + 2 Ether buffer = 35 Ether - New totalControlledEther value leads to increase of stETH.totalSupply and output of + New totalControlledEther value leads to increase of stETH.totalSupply and output of personal balances increased proportionally to holders' shares. */ const stat = await app.getEther2Stat() @@ -241,13 +239,13 @@ contract('DePool with StEth', ([appManager, voting, user1, user2, user3, nobody, it('stETH: totalSupply=35 user=34.99 treasury.003, insurance=.002, sp=.005', async () => { /* - New totalControlledEther value leads to increase of stETH.totalSupply, and output of + New totalControlledEther value leads to increase of stETH.totalSupply, and output of personal balances increased proportionally to holders' shares. Oracle's report also triggers fee payment that is substracted from the reward. The fee divides in given proportion between SPs, treasury and insurance vaults. userBalance = 34.0 Ether staked - shares = 34.0 + shares = 34.0 totalControlledEtherInitial = 34.0 Ether totalControlledEtherNew = 35.0 Ether reward = totalControlledEtherNew - totalControlledEtherInitial = 1.0 Ether @@ -436,11 +434,11 @@ contract('DePool with StEth', ([appManager, voting, user1, user2, user3, nobody, it('DePool: deposited=32, remote=66, buffered=2, totalControlled=68, rewBase=66', async () => { /* userBalance = 34.0 Ether staked - shares = 34.0 + shares = 34.0 totalControlledEtherInitial = 34.0 Ether totalControlledEtherNew = 68.0 Ether (66 remote + 2 buffer) reward = totalControlledEtherNew - totalControlledEtherInitial = 34.0 Ether - totalFee = reward * 0.01 = 0.34 stETH + totalFee = reward * 0.01 = 0.34 stETH userGets = reward - totalFee = 33.66 stETH userBalance = userBalance + reward - totalFee = 67.66 stETH treasuryBalance = totalFee * 0.3 = 0.102 diff --git a/test/0.4.24/depooloracle.test.js b/test/0.4.24/depooloracle.test.js index 6a950a289..4f3660857 100644 --- a/test/0.4.24/depooloracle.test.js +++ b/test/0.4.24/depooloracle.test.js @@ -1,7 +1,7 @@ const { assert } = require('chai') const { newDao, newApp } = require('./helpers/dao') -const { assertBn, assertRevert, assertEvent, assertAmountOfEvents } = require('@aragon/contract-helpers-test/src/asserts') -const { ONE_DAY, ZERO_ADDRESS, MAX_UINT64, bn, getEventArgument, injectWeb3, injectArtifacts } = require('@aragon/contract-helpers-test') +const { assertBn, assertRevert } = require('@aragon/contract-helpers-test/src/asserts') +const { bn } = require('@aragon/contract-helpers-test') const DePoolOracle = artifacts.require('TestDePoolOracle.sol') const Algorithm = artifacts.require('TestAlgorithm.sol') diff --git a/test/0.4.24/sps.test.js b/test/0.4.24/sps.test.js index b092c38e9..f491fca84 100644 --- a/test/0.4.24/sps.test.js +++ b/test/0.4.24/sps.test.js @@ -1,9 +1,6 @@ -const { join } = require('path') const { assert } = require('chai') const { newDao, newApp } = require('./helpers/dao') -const { assertBn, assertRevert, assertEvent, assertAmountOfEvents } = require('@aragon/contract-helpers-test/src/asserts') -const { ONE_DAY, ZERO_ADDRESS, MAX_UINT64, bn, getEventArgument, injectWeb3, injectArtifacts } = require('@aragon/contract-helpers-test') -const { BN } = require('bn.js') +const { assertBn, assertRevert } = require('@aragon/contract-helpers-test/src/asserts') const TestStakingProvidersRegistry = artifacts.require('TestStakingProvidersRegistry.sol') const PoolMock = artifacts.require('PoolMock.sol') @@ -45,7 +42,7 @@ contract('StakingProvidersRegistry', ([appManager, voting, user1, user2, user3, const { dao, acl } = await newDao(appManager) // Instantiate a proxy for the app, using the base contract as its logic implementation. - proxyAddress = await newApp(dao, 'staking-providers-registry', appBase.address, appManager) + const proxyAddress = await newApp(dao, 'staking-providers-registry', appBase.address, appManager) app = await TestStakingProvidersRegistry.at(proxyAddress) // Set up the app's permissions. diff --git a/test/0.4.24/steth.test.js b/test/0.4.24/steth.test.js index 8fce0a472..84a2ebf44 100644 --- a/test/0.4.24/steth.test.js +++ b/test/0.4.24/steth.test.js @@ -1,7 +1,6 @@ const { assert } = require('chai') const { newDao, newApp } = require('./helpers/dao') -const { assertBn, assertRevert, assertEvent, assertAmountOfEvents } = require('@aragon/contract-helpers-test/src/asserts') -const { ONE_DAY, ZERO_ADDRESS, MAX_UINT64, bn, getEventArgument, injectWeb3, injectArtifacts } = require('@aragon/contract-helpers-test') +const { assertBn, assertRevert } = require('@aragon/contract-helpers-test/src/asserts') const StETH = artifacts.require('StETH') const DePoolMock = artifacts.require('DePoolMock') diff --git a/test/scenario/depool_deposit_iteration_limit.js b/test/scenario/depool_deposit_iteration_limit.js index 41a07b831..03ebe0c38 100644 --- a/test/scenario/depool_deposit_iteration_limit.js +++ b/test/scenario/depool_deposit_iteration_limit.js @@ -1,3 +1,4 @@ +const { assert } = require('chai') const { assertBn, assertRevert } = require('@aragon/contract-helpers-test/src/asserts') const { getEvents, getEventArgument, ZERO_ADDRESS } = require('@aragon/contract-helpers-test') diff --git a/test/scenario/depool_happy_path.js b/test/scenario/depool_happy_path.js index 7858fa0cb..20f1a8295 100644 --- a/test/scenario/depool_happy_path.js +++ b/test/scenario/depool_happy_path.js @@ -5,7 +5,6 @@ const { getEventArgument } = require('@aragon/contract-helpers-test') const { pad, toBN, ETH, tokens } = require('../helpers/utils') const { deployDaoAndPool } = require('./helpers/deploy') -const { add } = require('winston') const StakingProvidersRegistry = artifacts.require('StakingProvidersRegistry') diff --git a/yarn.lock b/yarn.lock index d11b84981..165119a0d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1757,6 +1757,7 @@ __metadata: lint-staged: ">=10" openzeppelin-solidity: 2.0.0 prettier: ^2.1.2 + solhint: ^3.2.2 solidity-bytes-utils: 0.0.6 solidity-coverage: ^0.7.11 solium: ^1.2.5 @@ -3472,7 +3473,7 @@ __metadata: languageName: node linkType: hard -"@solidity-parser/parser@npm:^0.8.0": +"@solidity-parser/parser@npm:^0.8.0, @solidity-parser/parser@npm:^0.8.1": version: 0.8.1 resolution: "@solidity-parser/parser@npm:0.8.1" checksum: c16f7d947277d41cbef0b93df899e09ce1032a1ac37a2af9d9e3b805f38f232ae7516e3b41a4a81a2787cdc84dfe554d86aa6038faa899bac3254a653df68e39 @@ -4118,7 +4119,7 @@ __metadata: languageName: node linkType: hard -"acorn-jsx@npm:^5.2.0": +"acorn-jsx@npm:^5.0.0, acorn-jsx@npm:^5.2.0": version: 5.3.1 resolution: "acorn-jsx@npm:5.3.1" peerDependencies: @@ -4141,7 +4142,7 @@ __metadata: languageName: node linkType: hard -"acorn@npm:^6.0.1, acorn@npm:^6.0.4": +"acorn@npm:^6.0.1, acorn@npm:^6.0.4, acorn@npm:^6.0.7": version: 6.4.2 resolution: "acorn@npm:6.4.2" bin: @@ -4266,7 +4267,7 @@ __metadata: languageName: node linkType: hard -"ajv@npm:^6.10.0, ajv@npm:^6.10.2, ajv@npm:^6.12.3, ajv@npm:^6.12.4": +"ajv@npm:^6.10.0, ajv@npm:^6.10.2, ajv@npm:^6.12.3, ajv@npm:^6.12.4, ajv@npm:^6.6.1, ajv@npm:^6.9.1": version: 6.12.6 resolution: "ajv@npm:6.12.6" dependencies: @@ -4415,6 +4416,13 @@ __metadata: languageName: node linkType: hard +"antlr4@npm:4.7.1": + version: 4.7.1 + resolution: "antlr4@npm:4.7.1" + checksum: c8488c845f13f0d46b2d9475583d1df75d2b26f8cf59ecddf946fe3788e244ae3efabae8ad19846aa463c653d4307c50c87c0e14c24ed07def9fa22ee116cf75 + languageName: node + linkType: hard + "any-promise@npm:1.3.0, any-promise@npm:^1.0.0, any-promise@npm:^1.3.0": version: 1.3.0 resolution: "any-promise@npm:1.3.0" @@ -4795,6 +4803,13 @@ __metadata: languageName: node linkType: hard +"ast-parents@npm:0.0.1": + version: 0.0.1 + resolution: "ast-parents@npm:0.0.1" + checksum: 3902b2deacf336f7aa9b702402c6a6a20889f2cf9068cdc7e7ea6d00d1bea14bbf3b3954e459dd7ef90c1334766438258708fa5653948935edf6011ace169407 + languageName: node + linkType: hard + "astral-regex@npm:^1.0.0": version: 1.0.0 resolution: "astral-regex@npm:1.0.0" @@ -7333,6 +7348,13 @@ __metadata: languageName: node linkType: hard +"commander@npm:2.18.0": + version: 2.18.0 + resolution: "commander@npm:2.18.0" + checksum: 7864082c1b11498d763bbf217c9dab6b5829a759e04cf8fe60719e07ba779aec44509784b1a1fad19979b821e2767ed88013b258faf85ccd86e68fe5d52877d7 + languageName: node + linkType: hard + "commander@npm:3.0.2": version: 3.0.2 resolution: "commander@npm:3.0.2" @@ -7771,7 +7793,7 @@ __metadata: languageName: node linkType: hard -"cosmiconfig@npm:^5.0.0, cosmiconfig@npm:^5.1.0": +"cosmiconfig@npm:^5.0.0, cosmiconfig@npm:^5.0.7, cosmiconfig@npm:^5.1.0": version: 5.2.1 resolution: "cosmiconfig@npm:5.2.1" dependencies: @@ -9646,6 +9668,16 @@ __metadata: languageName: node linkType: hard +"eslint-scope@npm:^4.0.3": + version: 4.0.3 + resolution: "eslint-scope@npm:4.0.3" + dependencies: + esrecurse: ^4.1.0 + estraverse: ^4.1.1 + checksum: 49635cf9d936af317b9fa89cf98f30719ec9e287e5532c300cbab8015a1920b7ace495ffadaefd0ac86617ce85c17717f0ef1899f66536dca12aa85f1899899d + languageName: node + linkType: hard + "eslint-scope@npm:^5.1.1": version: 5.1.1 resolution: "eslint-scope@npm:5.1.1" @@ -9656,6 +9688,15 @@ __metadata: languageName: node linkType: hard +"eslint-utils@npm:^1.3.1": + version: 1.4.3 + resolution: "eslint-utils@npm:1.4.3" + dependencies: + eslint-visitor-keys: ^1.1.0 + checksum: 4a7ede9e723a859a8805bd1ae73681c99323be0da90d37799796ec564cc6c3326d57ac80f91667737abc45383170a3a90653e13c00c7368b3af9be0cec662b4c + languageName: node + linkType: hard + "eslint-utils@npm:^2.0.0, eslint-utils@npm:^2.1.0": version: 2.1.0 resolution: "eslint-utils@npm:2.1.0" @@ -9679,6 +9720,52 @@ __metadata: languageName: node linkType: hard +"eslint@npm:^5.6.0": + version: 5.16.0 + resolution: "eslint@npm:5.16.0" + dependencies: + "@babel/code-frame": ^7.0.0 + ajv: ^6.9.1 + chalk: ^2.1.0 + cross-spawn: ^6.0.5 + debug: ^4.0.1 + doctrine: ^3.0.0 + eslint-scope: ^4.0.3 + eslint-utils: ^1.3.1 + eslint-visitor-keys: ^1.0.0 + espree: ^5.0.1 + esquery: ^1.0.1 + esutils: ^2.0.2 + file-entry-cache: ^5.0.1 + functional-red-black-tree: ^1.0.1 + glob: ^7.1.2 + globals: ^11.7.0 + ignore: ^4.0.6 + import-fresh: ^3.0.0 + imurmurhash: ^0.1.4 + inquirer: ^6.2.2 + js-yaml: ^3.13.0 + json-stable-stringify-without-jsonify: ^1.0.1 + levn: ^0.3.0 + lodash: ^4.17.11 + minimatch: ^3.0.4 + mkdirp: ^0.5.1 + natural-compare: ^1.4.0 + optionator: ^0.8.2 + path-is-inside: ^1.0.2 + progress: ^2.0.0 + regexpp: ^2.0.1 + semver: ^5.5.1 + strip-ansi: ^4.0.0 + strip-json-comments: ^2.0.1 + table: ^5.2.3 + text-table: ^0.2.0 + bin: + eslint: ./bin/eslint.js + checksum: 420ee3bc29782f325b44e5ef747525b120836954c94caeb2314ec127508e64105125ad71a7c68f4cac0b6a27573e8cf87b17d3ee292e96fc23feacd3e00ab931 + languageName: node + linkType: hard + "eslint@npm:^7.9.0": version: 7.11.0 resolution: "eslint@npm:7.11.0" @@ -9726,6 +9813,17 @@ __metadata: languageName: node linkType: hard +"espree@npm:^5.0.1": + version: 5.0.1 + resolution: "espree@npm:5.0.1" + dependencies: + acorn: ^6.0.7 + acorn-jsx: ^5.0.0 + eslint-visitor-keys: ^1.0.0 + checksum: 577bc6fc8a2a697ec60abe05db9c6b19229ed5964d4ad0071fd9c3d5990edc4050c5ac522b5cdc944769d23ad213c492b5a4ee33afa4ee05b6b5f37c1673e2f5 + languageName: node + linkType: hard + "espree@npm:^7.3.0": version: 7.3.0 resolution: "espree@npm:7.3.0" @@ -9767,7 +9865,7 @@ __metadata: languageName: node linkType: hard -"esquery@npm:^1.2.0": +"esquery@npm:^1.0.1, esquery@npm:^1.2.0": version: 1.3.1 resolution: "esquery@npm:1.3.1" dependencies: @@ -9776,7 +9874,7 @@ __metadata: languageName: node linkType: hard -"esrecurse@npm:^4.3.0": +"esrecurse@npm:^4.1.0, esrecurse@npm:^4.3.0": version: 4.3.0 resolution: "esrecurse@npm:4.3.0" dependencies: @@ -12108,7 +12206,7 @@ __metadata: languageName: node linkType: hard -"glob@npm:7.1.6, glob@npm:^7.0.0, glob@npm:^7.0.3, glob@npm:^7.0.5, glob@npm:^7.1.1, glob@npm:^7.1.3, glob@npm:^7.1.4, glob@npm:~7.1.6": +"glob@npm:7.1.6, glob@npm:^7.0.0, glob@npm:^7.0.3, glob@npm:^7.0.5, glob@npm:^7.1.1, glob@npm:^7.1.2, glob@npm:^7.1.3, glob@npm:^7.1.4, glob@npm:~7.1.6": version: 7.1.6 resolution: "glob@npm:7.1.6" dependencies: @@ -12183,7 +12281,7 @@ __metadata: languageName: node linkType: hard -"globals@npm:^11.1.0": +"globals@npm:^11.1.0, globals@npm:^11.7.0": version: 11.12.0 resolution: "globals@npm:11.12.0" checksum: 2563d3306a7e646fd9ec484b0ca29bf8847d9dc6ebbe86026f11e31bda04f420f6536c2decbd4cb96350379801d2cce352ab373c40be8b024324775b31f882f9 @@ -13194,7 +13292,7 @@ __metadata: languageName: node linkType: hard -"inquirer@npm:^6.2.0": +"inquirer@npm:^6.2.0, inquirer@npm:^6.2.2": version: 6.5.2 resolution: "inquirer@npm:6.5.2" dependencies: @@ -14626,7 +14724,7 @@ __metadata: languageName: node linkType: hard -"js-yaml@npm:3.14.0, js-yaml@npm:3.x, js-yaml@npm:^3.10.0, js-yaml@npm:^3.13.1": +"js-yaml@npm:3.14.0, js-yaml@npm:3.x, js-yaml@npm:^3.10.0, js-yaml@npm:^3.12.0, js-yaml@npm:^3.13.0, js-yaml@npm:^3.13.1": version: 3.14.0 resolution: "js-yaml@npm:3.14.0" dependencies: @@ -15330,6 +15428,16 @@ __metadata: languageName: node linkType: hard +"levn@npm:^0.3.0, levn@npm:~0.3.0": + version: 0.3.0 + resolution: "levn@npm:0.3.0" + dependencies: + prelude-ls: ~1.1.2 + type-check: ~0.3.2 + checksum: 775861da38dcb7e5f1de5bea2a1c7ffaede6e9e8632cfbac76be145ecb295370f46bb41307613c283d66f1fee5d8cc448ca3323c4a02d0fb1e913b2f78de2abb + languageName: node + linkType: hard + "levn@npm:^0.4.1": version: 0.4.1 resolution: "levn@npm:0.4.1" @@ -15340,16 +15448,6 @@ __metadata: languageName: node linkType: hard -"levn@npm:~0.3.0": - version: 0.3.0 - resolution: "levn@npm:0.3.0" - dependencies: - prelude-ls: ~1.1.2 - type-check: ~0.3.2 - checksum: 775861da38dcb7e5f1de5bea2a1c7ffaede6e9e8632cfbac76be145ecb295370f46bb41307613c283d66f1fee5d8cc448ca3323c4a02d0fb1e913b2f78de2abb - languageName: node - linkType: hard - "libp2p-crypto-secp256k1@npm:~0.2.2": version: 0.2.3 resolution: "libp2p-crypto-secp256k1@npm:0.2.3" @@ -17933,7 +18031,7 @@ __metadata: languageName: node linkType: hard -"optionator@npm:^0.8.1": +"optionator@npm:^0.8.1, optionator@npm:^0.8.2": version: 0.8.3 resolution: "optionator@npm:0.8.3" dependencies: @@ -19489,6 +19587,15 @@ __metadata: languageName: node linkType: hard +"prettier@npm:^1.14.3": + version: 1.19.1 + resolution: "prettier@npm:1.19.1" + bin: + prettier: ./bin-prettier.js + checksum: e5fcdfe5e159ef5c5480245353cf8fb5bbd1b8afff266f31f281641825238f8a645e58472f77cd75a09ccc45d44c335466e8d901ec138c2bda05e1bd6ea1077c + languageName: node + linkType: hard + "prettier@npm:^2.1.2": version: 2.1.2 resolution: "prettier@npm:2.1.2" @@ -20556,6 +20663,13 @@ __metadata: languageName: node linkType: hard +"regexpp@npm:^2.0.1": + version: 2.0.1 + resolution: "regexpp@npm:2.0.1" + checksum: e537f6c1b59f31a8d6381c64408d7a852aa98794896702fdadef2fa8b049f7d876da30cd0c6f6a64488aa58ad3b225d606cc689059628056b5a593e5422c38d6 + languageName: node + linkType: hard + "regexpp@npm:^3.0.0, regexpp@npm:^3.1.0": version: 3.1.0 resolution: "regexpp@npm:3.1.0" @@ -21800,6 +21914,34 @@ resolve@1.1.x: languageName: node linkType: hard +"solhint@npm:^3.2.2": + version: 3.2.2 + resolution: "solhint@npm:3.2.2" + dependencies: + "@solidity-parser/parser": ^0.8.1 + ajv: ^6.6.1 + antlr4: 4.7.1 + ast-parents: 0.0.1 + chalk: ^2.4.2 + commander: 2.18.0 + cosmiconfig: ^5.0.7 + eslint: ^5.6.0 + fast-diff: ^1.1.2 + glob: ^7.1.3 + ignore: ^4.0.6 + js-yaml: ^3.12.0 + lodash: ^4.17.11 + prettier: ^1.14.3 + semver: ^6.3.0 + dependenciesMeta: + prettier: + optional: true + bin: + solhint: solhint.js + checksum: 4b77b5d6490233ec49899149b103ebec33518fcb5eee4a2078a363e8b7d8247c9edeed3650bce37e180fe777da88eba8abdbb946d3933fa1558fb1d1a809ebce + languageName: node + linkType: hard + "solidity-bytes-utils@npm:0.0.6": version: 0.0.6 resolution: "solidity-bytes-utils@npm:0.0.6" @@ -22590,7 +22732,7 @@ resolve@1.1.x: languageName: node linkType: hard -"strip-json-comments@npm:2.0.1, strip-json-comments@npm:~2.0.1": +"strip-json-comments@npm:2.0.1, strip-json-comments@npm:^2.0.1, strip-json-comments@npm:~2.0.1": version: 2.0.1 resolution: "strip-json-comments@npm:2.0.1" checksum: e60d99aa2849c27a04dce0620334f45822197df6b83664dd3746971e9a0a766d989dbb8d87f9cb7350725d2b5df401a2343222ad06e36a1ba7d62c6633267fcb