Skip to content

Commit 70a5c0a

Browse files
ArvoleararitkulovaKyrylRmllwchrry
authored
Solarity 3.0 (#131)
* Updated OpenZeppelin to version 5.1.0 (#109) * updated dependencies * specified initialOwner for __Ownable_init function * MathUpgradeable lib -> Math lib * created mock contract for ERC721Holder * updated test's error handlers to catch custom errors * fixed typo in test * Added custom TransparentUpgradeableProxy contract * Removed isContract() * Fixed typo * Cleaned up dependencies * Dropped tests for isContract() check in Diamond * Removed unnecessary dependency * Added solhint command to scripts * Renamed TransparentUpgradeableProxy to avoid collisions * Updated dependencies * Fixed package-lock * Switched to custom errors in contracts (#113) * Switched to custom errors in contracts * Review fixes: removed prefixes; removed redundant comments; refactored namings; added args to errors. * require -> revert in vectorMock * Remover unused imports * Review: removed zero args; added useful args. * Ordering errors in alphabetical order * Splited Traversal into separate file * review fixes; linting; errors are located at the top of file. * switched to own custom error instead of erc20 in DiamondERC20 * Explicitly marked visibility of state in mock contract * Fixed typo * Typo InvalidMaxDepth -> MaxDepthIsZero * switched to revertedWithCustomError in tests * Switched to custom error in RawReturnMock * Added testcase for _checkOnERC721Received. Coverage is 100% * Cleanup: ZERO_ADDR -> ZeroAddress from ethers; ordered imports in tests. * Specified import * Replaced ZERO_BYTES32 with ethers.ZeroHash * Replaced ZERO_ADDRESS with ethers.ZeroAddress * Updated .solhint config. Resolved solhint warnings --------- Co-authored-by: Kyryl Riabov <kyryl.ryabov@gmail.com> * Added missed .withArgs() to error handlers * Updated .solhint config * Updated versions * updated openzeppelin to 5.1.0 * review fixes: linting * renamed TransparentProxy to AdminableProxy * moved IAdminableProxy to the interfaces; moved VerifierHelper out of snarkjs dir. * switched from staticcall to call through interface in AdminableProxyUpgrader * updated dev dependencies * downgraded types/chai and types/node * renamed transparent dir to adminable * placed Traversal lib into AvlTree file * erc721: - deleted `_beforeTokenTransfer` and `_afterTokenTransfer` hooks; - added a new `_update` function for customizations * erc20: - deleted `_beforeTokenTransfer` and `_afterTokenTransfer` hooks; - added a new `_update` function for customizations * linting * linting --------- Co-authored-by: Kyryl Riabov <kyryl.ryabov@gmail.com> * Updated pragma solidity to ^0.8.21 + renamed Abstract contracts (#116) * Updated crypto libs for v3.0.0 (#118) * Crypto libs (#115) * added ecdsa384 lib * added rsassapss * try fix ci * fix callvalue * Added tests covering the `verify` and `_isOnCurve` functions * fix coverage * split getModifiedSigOrPubKey into modifyLeft and modifyRight * Added tests covering the RSASSAPSS lib * switched to assert two unreachable conditions * fixed typos in test * removed unused functions in U384 lib * added test for a U384.cmp function * trying to fix test for cmp * add brainpoolP384r1 test --------- Co-authored-by: aritkulova <aritkulova.yuliia@gmail.com> * updated crypto lib contracts: - pragma solidity; - solhint; - custom errors * updated missed pragma solidity * fixed typo in README --------- Co-authored-by: Artem Chystiakov <47551140+Arvolear@users.noreply.github.com> * updated: - ecdsa256 contract (pragma solidity, solhint, custom errors); - package lock * refactor and add reinitializer * update readme --------- Co-authored-by: Yuliia Aritkulova <94910987+aritkulova@users.noreply.github.com> Co-authored-by: Kyryl Riabov <kyryl.ryabov@gmail.com> Co-authored-by: aritkulova <aritkulova.yuliia@gmail.com> Co-authored-by: mllwchrry <mariia.zhvanko@gmail.com>
1 parent 97aba26 commit 70a5c0a

File tree

175 files changed

+3965
-4868
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

175 files changed

+3965
-4868
lines changed

.solhint.json

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,14 @@
33
"plugins": ["prettier"],
44
"rules": {
55
"prettier/prettier": "warn",
6-
"reentrancy": "off",
7-
"modifier-name-mixedcase": "off",
6+
"reentrancy": "warn",
7+
"modifier-name-mixedcase": "warn",
88
"no-empty-blocks": "off",
9-
"func-visibility": "off",
10-
"max-states-count": "off",
9+
"func-visibility": ["warn", { "ignoreConstructors": true }],
10+
"max-states-count": "warn",
1111
"not-rely-on-time": "off",
12-
"compiler-version": "off"
12+
"func-name-mixedcase": "off",
13+
"no-inline-assembly": "off",
14+
"compiler-version": ["off"]
1315
}
1416
}

README.md

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
66
[![GitPOAP Badge](https://public-api.gitpoap.io/v1/repo/dl-solarity/solidity-lib/badge)](https://www.gitpoap.io/gh/dl-solarity/solidity-lib)
77

8-
# Solidity Library for Savvies
8+
# Solarity Solidity Library
99

1010
Solidity modules and utilities that **go far beyond mediocre solidity**.
1111

@@ -21,7 +21,7 @@ Solidity modules and utilities that **go far beyond mediocre solidity**.
2121
- Hyperoptimized **uint512** BigInt library
2222
- Utilities to ease work with memory, types, ERC20 decimals, arrays, sets, and ZK proofs
2323

24-
Built leveraging [OpenZeppelin Contracts](https://github.com/OpenZeppelin/openzeppelin-contracts) (4.9.6).
24+
Built with courage and aspiration to perfection.
2525

2626
## Overview
2727

@@ -44,17 +44,44 @@ You will find the smart contracts in the `/contracts` directory. Feel free to pl
4444
Once the [npm package](https://www.npmjs.com/package/@solarity/solidity-lib) is installed, one can use the library just like that:
4545

4646
```solidity
47-
pragma solidity ^0.8.4;
48-
49-
import {OwnableContractsRegistry} from "@solarity/solidity-lib/contracts-registry/presets/OwnableContractsRegistry.sol";
50-
51-
contract ContractsRegistry is OwnableContractsRegistry {
52-
. . .
47+
pragma solidity ^0.8.21;
48+
49+
import {AMultiOwnable} from "@solarity/solidity-lib/access/AMultiOwnable.sol";
50+
import {TypeCaster} from "@solarity/solidity-lib/libs/utils/TypeCaster.sol";
51+
import {CartesianMerkleTree} from "@solarity/solidity-lib/libs/data-structures/CartesianMerkleTree.sol";
52+
import {Groth16VerifierHelper} from "@solarity/solidity-lib/libs/zkp/Groth16VerifierHelper.sol";
53+
54+
contract Example is AMultiOwnable {
55+
using CartesianMerkleTree for CartesianMerkleTree.UintCMT;
56+
using Groth16VerifierHelper for address;
57+
58+
CartesianMerkleTree.UintCMT internal _uintTreaple;
59+
address internal _treapleVerifier;
60+
61+
function __Example_init(address treapleVerifier_) initializer {
62+
__AMultiOwnable_init();
63+
_uintTreaple.initialize(40);
64+
_treapleVerifier = treapleVerifier_;
65+
}
66+
67+
function addToTree(uint256 key_) external onlyOwner {
68+
_uintTreaple.add(key_);
69+
}
70+
71+
function getMerkleProof(uint256 key_) external view returns (CartesianMerkleTree.Proof memory) {
72+
return _uintTreaple.getProof(key_, 0);
73+
}
74+
75+
function verifyZKProof(Groth16VerifierHelper.ProofPoints memory proof_) external view {
76+
uint256[] memory pubSignals_ = TypeCaster.asSingletonArray(_uintTreaple.getRoot());
77+
78+
require(_treapleVerifier.verifyProof(pubSignals_, proof_), "ZKP verification failed");
79+
}
5380
}
5481
```
5582

56-
> [!IMPORTANT]
57-
> It is important to use the library as it is shipped and not copy-paste the code from untrusted sources.
83+
> [!TIP]
84+
> The library is designed to work cohesively with [hardhat-zkit](https://github.com/dl-solarity/hardhat-zkit) and [circom-lib](https://github.com/dl-solarity/circom-lib) packages.
5885
5986
## Contribution
6087

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// SPDX-License-Identifier: MIT
2-
pragma solidity ^0.8.4;
2+
pragma solidity ^0.8.21;
33

44
import {MerkleProof} from "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol";
55

@@ -17,21 +17,21 @@ import {MerkleProof} from "@openzeppelin/contracts/utils/cryptography/MerkleProo
1717
*
1818
* Note: the branch nodes are sorted numerically.
1919
*/
20-
abstract contract MerkleWhitelisted {
20+
abstract contract AMerkleWhitelisted {
2121
using MerkleProof for bytes32[];
2222

2323
bytes32 private _merkleRoot;
2424

25+
error LeafNotWhitelisted(bytes data);
26+
error UserNotWhitelisted(address user);
27+
2528
modifier onlyWhitelisted(bytes memory data_, bytes32[] memory merkleProof_) {
26-
require(
27-
_isWhitelisted(keccak256(data_), merkleProof_),
28-
"MerkleWhitelisted: not whitelisted"
29-
);
29+
if (!_isWhitelisted(keccak256(data_), merkleProof_)) revert LeafNotWhitelisted(data_);
3030
_;
3131
}
3232

3333
modifier onlyWhitelistedUser(address user_, bytes32[] memory merkleProof_) {
34-
require(_isWhitelistedUser(user_, merkleProof_), "MerkleWhitelisted: not whitelisted");
34+
if (!_isWhitelistedUser(user_, merkleProof_)) revert UserNotWhitelisted(user_);
3535
_;
3636
}
3737

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// SPDX-License-Identifier: MIT
2-
pragma solidity ^0.8.4;
2+
pragma solidity ^0.8.21;
33

44
import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
55
import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
@@ -21,13 +21,16 @@ import {IMultiOwnable} from "../interfaces/access/IMultiOwnable.sol";
2121
* This module will make available the modifier `onlyOwner`, which can be applied
2222
* to your functions to restrict their use to the owners.
2323
*/
24-
abstract contract MultiOwnable is IMultiOwnable, Initializable {
24+
abstract contract AMultiOwnable is IMultiOwnable, Initializable {
2525
using EnumerableSet for EnumerableSet.AddressSet;
2626
using TypeCaster for address;
2727
using SetHelper for EnumerableSet.AddressSet;
2828

2929
EnumerableSet.AddressSet private _owners;
3030

31+
error InvalidOwner();
32+
error UnauthorizedAccount(address account);
33+
3134
modifier onlyOwner() {
3235
_checkOwner();
3336
_;
@@ -36,7 +39,7 @@ abstract contract MultiOwnable is IMultiOwnable, Initializable {
3639
/**
3740
* @dev Initializes the contract setting the msg.sender as the initial owner.
3841
*/
39-
function __MultiOwnable_init() internal onlyInitializing {
42+
function __AMultiOwnable_init() internal onlyInitializing {
4043
_addOwners(msg.sender.asSingletonArray());
4144
}
4245

@@ -91,7 +94,7 @@ abstract contract MultiOwnable is IMultiOwnable, Initializable {
9194
function _addOwners(address[] memory newOwners_) private {
9295
_owners.add(newOwners_);
9396

94-
require(!_owners.contains(address(0)), "MultiOwnable: zero address can not be added");
97+
if (_owners.contains(address(0))) revert InvalidOwner();
9598

9699
emit OwnersAdded(newOwners_);
97100
}
@@ -115,6 +118,6 @@ abstract contract MultiOwnable is IMultiOwnable, Initializable {
115118
* @dev Throws if the sender is not the owner.
116119
*/
117120
function _checkOwner() private view {
118-
require(isOwner(msg.sender), "MultiOwnable: caller is not the owner");
121+
if (!isOwner(msg.sender)) revert UnauthorizedAccount(msg.sender);
119122
}
120123
}
Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// SPDX-License-Identifier: MIT
2-
pragma solidity ^0.8.4;
2+
pragma solidity ^0.8.21;
33

44
/**
55
* @notice The PermanentOwnable module
@@ -12,9 +12,12 @@ pragma solidity ^0.8.4;
1212
* This module will make available the modifier `onlyOwner`, which can be applied
1313
* to your functions to restrict their use to the owners.
1414
*/
15-
abstract contract PermanentOwnable {
15+
abstract contract APermanentOwnable {
1616
address private immutable _OWNER;
1717

18+
error InvalidOwner();
19+
error UnauthorizedAccount(address account);
20+
1821
/**
1922
* @dev Throws if called by any account other than the owner.
2023
*/
@@ -28,7 +31,7 @@ abstract contract PermanentOwnable {
2831
* @param owner_ the address of the permanent owner.
2932
*/
3033
constructor(address owner_) {
31-
require(owner_ != address(0), "PermanentOwnable: zero address can not be the owner");
34+
if (owner_ == address(0)) revert InvalidOwner();
3235

3336
_OWNER = owner_;
3437
}
@@ -42,6 +45,6 @@ abstract contract PermanentOwnable {
4245
}
4346

4447
function _onlyOwner() internal view virtual {
45-
require(_OWNER == msg.sender, "PermanentOwnable: caller is not the owner");
48+
if (_OWNER != msg.sender) revert UnauthorizedAccount(msg.sender);
4649
}
4750
}
Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// SPDX-License-Identifier: MIT
2-
pragma solidity ^0.8.4;
2+
pragma solidity ^0.8.21;
33

44
import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
55

@@ -30,7 +30,7 @@ import {DynamicSet} from "../libs/data-structures/DynamicSet.sol";
3030
*
3131
* Where ROLE is assignable to users
3232
*/
33-
abstract contract RBAC is IRBAC, Initializable {
33+
abstract contract ARBAC is IRBAC, Initializable {
3434
using DynamicSet for DynamicSet.StringSet;
3535
using SetHelper for DynamicSet.StringSet;
3636
using TypeCaster for string;
@@ -53,20 +53,19 @@ abstract contract RBAC is IRBAC, Initializable {
5353

5454
mapping(address => DynamicSet.StringSet) private _userRoles;
5555

56+
error EmptyRoles();
57+
error NoPermissionForResource(address account, string permission, string resource);
58+
5659
modifier onlyPermission(string memory resource_, string memory permission_) {
57-
require(
58-
hasPermission(msg.sender, resource_, permission_),
59-
string(
60-
abi.encodePacked("RBAC: no ", permission_, " permission for resource ", resource_)
61-
)
62-
);
60+
if (!hasPermission(msg.sender, resource_, permission_))
61+
revert NoPermissionForResource(msg.sender, permission_, resource_);
6362
_;
6463
}
6564

6665
/**
6766
* @notice The initialization function
6867
*/
69-
function __RBAC_init() internal onlyInitializing {
68+
function __ARBAC_init() internal onlyInitializing {
7069
_addPermissionsToRole(MASTER_ROLE, ALL_RESOURCE, ALL_PERMISSION.asSingletonArray(), true);
7170
}
7271

@@ -79,7 +78,7 @@ abstract contract RBAC is IRBAC, Initializable {
7978
address to_,
8079
string[] memory rolesToGrant_
8180
) public virtual override onlyPermission(RBAC_RESOURCE, CREATE_PERMISSION) {
82-
require(rolesToGrant_.length > 0, "RBAC: empty roles");
81+
if (rolesToGrant_.length == 0) revert EmptyRoles();
8382

8483
_grantRoles(to_, rolesToGrant_);
8584
}
@@ -93,7 +92,7 @@ abstract contract RBAC is IRBAC, Initializable {
9392
address from_,
9493
string[] memory rolesToRevoke_
9594
) public virtual override onlyPermission(RBAC_RESOURCE, DELETE_PERMISSION) {
96-
require(rolesToRevoke_.length > 0, "RBAC: empty roles");
95+
if (rolesToRevoke_.length == 0) revert EmptyRoles();
9796

9897
_revokeRoles(from_, rolesToRevoke_);
9998
}

contracts/access/extensions/RBACGroupable.sol renamed to contracts/access/extensions/ARBACGroupable.sol

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
// SPDX-License-Identifier: MIT
2-
pragma solidity ^0.8.4;
2+
pragma solidity ^0.8.21;
33

44
import {IRBACGroupable} from "../../interfaces/access/extensions/IRBACGroupable.sol";
55

66
import {DynamicSet} from "../../libs/data-structures/DynamicSet.sol";
77
import {SetHelper} from "../../libs/arrays/SetHelper.sol";
88

9-
import {RBAC} from "../RBAC.sol";
9+
import {ARBAC} from "../ARBAC.sol";
1010

1111
/**
1212
* @notice The Role Based Access Control (RBAC) module
@@ -22,7 +22,7 @@ import {RBAC} from "../RBAC.sol";
2222
*
2323
* Where ROLE and GROUP are assignable to users
2424
*/
25-
abstract contract RBACGroupable is IRBACGroupable, RBAC {
25+
abstract contract ARBACGroupable is IRBACGroupable, ARBAC {
2626
using DynamicSet for DynamicSet.StringSet;
2727
using SetHelper for DynamicSet.StringSet;
2828

@@ -31,11 +31,13 @@ abstract contract RBACGroupable is IRBACGroupable, RBAC {
3131
mapping(address => DynamicSet.StringSet) private _userGroups;
3232
mapping(string => DynamicSet.StringSet) private _groupRoles;
3333

34+
error EmptyGroups();
35+
3436
/**
3537
* @notice The initialization function
3638
*/
37-
function __RBACGroupable_init() internal onlyInitializing {
38-
__RBAC_init();
39+
function __ARBACGroupable_init() internal onlyInitializing {
40+
__ARBAC_init();
3941
}
4042

4143
/**
@@ -47,7 +49,7 @@ abstract contract RBACGroupable is IRBACGroupable, RBAC {
4749
address who_,
4850
string[] memory groupsToAddTo_
4951
) public virtual override onlyPermission(RBAC_RESOURCE, CREATE_PERMISSION) {
50-
require(groupsToAddTo_.length > 0, "RBACGroupable: empty groups");
52+
if (groupsToAddTo_.length == 0) revert EmptyGroups();
5153

5254
_addUserToGroups(who_, groupsToAddTo_);
5355
}
@@ -61,7 +63,7 @@ abstract contract RBACGroupable is IRBACGroupable, RBAC {
6163
address who_,
6264
string[] memory groupsToRemoveFrom_
6365
) public virtual override onlyPermission(RBAC_RESOURCE, DELETE_PERMISSION) {
64-
require(groupsToRemoveFrom_.length > 0, "RBACGroupable: empty groups");
66+
if (groupsToRemoveFrom_.length == 0) revert EmptyGroups();
6567

6668
_removeUserFromGroups(who_, groupsToRemoveFrom_);
6769
}
@@ -75,7 +77,7 @@ abstract contract RBACGroupable is IRBACGroupable, RBAC {
7577
string memory groupTo_,
7678
string[] memory rolesToGrant_
7779
) public virtual override onlyPermission(RBAC_RESOURCE, CREATE_PERMISSION) {
78-
require(rolesToGrant_.length > 0, "RBACGroupable: empty roles");
80+
if (rolesToGrant_.length == 0) revert EmptyRoles();
7981

8082
_grantGroupRoles(groupTo_, rolesToGrant_);
8183
}
@@ -89,7 +91,7 @@ abstract contract RBACGroupable is IRBACGroupable, RBAC {
8991
string memory groupFrom_,
9092
string[] memory rolesToRevoke_
9193
) public virtual override onlyPermission(RBAC_RESOURCE, DELETE_PERMISSION) {
92-
require(rolesToRevoke_.length > 0, "RBACGroupable: empty roles");
94+
if (rolesToRevoke_.length == 0) revert EmptyRoles();
9395

9496
_revokeGroupRoles(groupFrom_, rolesToRevoke_);
9597
}

0 commit comments

Comments
 (0)