Rigor Protocol contest - Rolezn's results

Community lending and instant payments for new home construction.

General Information

Platform: Code4rena

Start Date: 01/08/2022

Pot Size: $50,000 USDC

Total HM: 26

Participants: 133

Period: 5 days

Judge: Jack the Pug

Total Solo HM: 6

Id: 151

League: ETH

Rigor Protocol

Findings Distribution

Researcher Performance

Rank: 67/133

Findings: 2

Award: $62.64

๐ŸŒŸ Selected for report: 0

๐Ÿš€ Solo Findings: 0

(1) Missing Checks for Address(0x0)

Severity: Low

Proof Of Concept

function _unpublishProject(address _project) internal {

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Community.sol#L726

function setTrustedForwarder(address _newForwarder) external override onlyAdmin noChange(trustedForwarder, _newForwarder) {

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/HomeFi.sol#L200

function initialize( address _currency, address _sender, address _homeFiAddress ) external override initializer {

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Project.sol#L94

function initialize( address _currency, address _sender, address _homeFiAddress ) external override initializer {

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Project.sol#L94

function initialize( address _currency, address _sender, address _homeFiAddress ) external override initializer {

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Project.sol#L94

function recoverTokens(address _tokenAddress) external override {

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Project.sol#L362

function createProject(address _currency, address _sender) external override returns (address _clone) {

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/ProjectFactory.sol#L78

Consider adding zero-address checks in the mentioned codebase.

(2) Transferownership Should Be Two Step

Severity: Low

The owner is the authorized user in the solidity contracts. Usually, an owner can be updated with transferOwnership function. However, the process is only completed with single transaction. If the address is updated incorrectly, an owner functionality will be lost forever.

Proof Of Concept

proxyAdmin.transferOwnership(_newAdmin);

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/HomeFiProxy.sol#L156

Lack of two-step procedure for critical operations leaves them error-prone. Consider adding two step procedure on the critical functions.

(3) Use _safeMint instead of _mint

Severity: Low

According to openzepplin's ERC721, the use of _mint is discouraged, use _safeMint whenever possible. https://docs.openzeppelin.com/contracts/3.x/api/token/erc721#ERC721-_mint-address-uint256-

Proof Of Concept

_mint(_to, _total);

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/DebtToken.sol#L66

_mint(_to, projectCount);

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/HomeFi.sol#L292

(4) Update OpenZeppelin Packages to ^4.7.0

Severity: Low

According to package.json, the OZ packages are currently set to ^4.4.2

Proof Of Concept

"@openzeppelin/contracts": "^4.4.2", "@openzeppelin/contracts-upgradeable": "^4.4.2"

https://github.com/code-423n4/2022-08-rigor/blob/main/package.json#L68-L69

Update the versions of @openzeppelin/contracts and @openzeppelin/contracts-upgradeable to be the latest in package.json. I also recommend double checking the versions of other dependencies as a precaution, as they may include important bug fixes.

(5) Missing NATSPEC Documentation

Severity: Non-Critical

Proof Of Concept

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/HomeFi.sol https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Community.sol https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/DebtToken.sol https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/ProjectFactory.sol https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Disputes.sol https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/HomeFiProxy.sol https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Disputes.sol https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/libraries/Tasks.sol

(6) Incorrect Documentation

Severity: Non-Critical

Proof Of Concept

* @return _tokenIds NFT Id of project

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/HomeFi.sol#L282

Is incorrect as it returns projectCount and not _tokenIds

(7) Constants Should Be Defined Rather Than Using Magic Numbers

Severity: Non-Critical

Proof Of Concept

(_projectInstance.lenderFee() + 1000);

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Community.sol#L394

uint256 _maxLoop = 50;

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Project.sol#L576

((_amount / 1000) * 1000) == _amount,

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Project.sol#L907

if (v != 27 && v != 28) {

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/libraries/SignatureDecoder.sol#L35

if (v < 27) {

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/libraries/SignatureDecoder.sol#L82

(8) Inconsistent Spacing In Comments

Severity: Non-Critical

Some lines use // x and some use //x. The instances below point out the usages that donโ€™t follow the majority, within each file

Proof Of Concept

uint256 public override disputeCount; //starts from 0

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Disputes.sol#L29

(9) Missing event for critical parameter change

Severity: Non-Critical

Proof Of Concept

function setTrustedForwarder(

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/HomeFi.sol#L200

function changeProxyAdminOwner(

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/HomeFiProxy.sol#L150

function changeOrderedTask(

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Project.sol#L559

function changeProjectImplementation(

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/ProjectFactory.sol#L58

function setComplete(

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/libraries/Tasks.sol#L88

(10) Implementation contract may not be initialized

OpenZeppelin recommends that the initializer modifier be applied to constructors. Per OZs Post implementation contract should be initialized to avoid potential griefs or exploits. https://forum.openzeppelin.com/t/uupsupgradeable-vulnerability-post-mortem/15680/5

Severity: Non-Critical

Proof Of Concept

contract Community is ICommunity, PausableUpgradeable, ReentrancyGuardUpgradeable, ERC2771ContextUpgradeable

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Community.sol#L21

contract DebtToken is IDebtToken, ERC20Upgradeable

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/DebtToken.sol#L11

contract Disputes is IDisputes, ReentrancyGuardUpgradeable, ERC2771ContextUpgradeable

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Disputes.sol#L17

contract HomeFi is IHomeFi, ReentrancyGuardUpgradeable, ERC721URIStorageUpgradeable, ERC2771ContextUpgradeable

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/HomeFi.sol#L27

contract HomeFiProxy is OwnableUpgradeable

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/HomeFiProxy.sol#L14

contract ProjectFactory is IProjectFactory, Initializable, ERC2771ContextUpgradeable

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/ProjectFactory.sol#L16

(11) Use a more recent version of Solidity

Severity: Non-Critical

Use a solidity version of at least 0.8.12 to get string.concat() instead of abi.encodePacked(<str>,<str>) Use a solidity version of at least 0.8.13 to get the ability to use using for with a list of free functions

Proof Of Concept

Found old version 0.8.6 of Solidity https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Community.sol#L3

Found old version 0.8.6 of Solidity https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/DebtToken.sol#L3

Found old version 0.8.6 of Solidity https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Disputes.sol#L3

Found old version 0.8.6 of Solidity https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/HomeFi.sol#L3

Found old version 0.8.6 of Solidity https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/HomeFiProxy.sol#L3

Found old version 0.8.6 of Solidity https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Project.sol#L3

Found old version 0.8.6 of Solidity https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/ProjectFactory.sol#L3

Found old version 0.8.6 of Solidity https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/libraries/SignatureDecoder.sol#L3

Found old version 0.8.6 of Solidity https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/libraries/Tasks.sol#L3

Consider updating to a more recent solidity version.

(1) <Array>.length Should Not Be Looked Up In Every Loop Of A For-loop

Severity: Gas Optimizations

The overheads outlined below are PER LOOP, excluding the first loop

storage arrays incur a Gwarmaccess (100 gas) memory arrays use MLOAD (3 gas) calldata arrays use CALLDATALOAD (3 gas)

Caching the length changes each of these to a DUP<N> (3 gas), and gets rid of the extra DUP<N> needed to store the stack offset

Proof Of Concept

for (; i < _changeOrderedTask.length; i++) {

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Project.sol#L603

(2) ++i Costs Less Gas Than i++, Especially When Itโ€™s Used In For-loops (--i/i-- Too)

Severity: Gas Optimizations

Saves 6 gas per loop

Proof Of Concept

for (uint256 i = 0; i < _communities[_communityID].memberCount; i++) {

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Community.sol#L624

for (uint256 i = 0; i < _length; i++) {

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/HomeFiProxy.sol#L87

for (uint256 i = 0; i < _length; i++) {

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/HomeFiProxy.sol#L136

for (uint256 i = 0; i < _length; i++) {

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Project.sol#L248

for (uint256 i = 0; i < _length; i++) {

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Project.sol#L311

for (uint256 i = 0; i < _length; i++) {

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Project.sol#L322

for (; i < _changeOrderedTask.length; i++) {

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Project.sol#L603

for (uint256 _taskID = 1; _taskID <= _length; _taskID++) {

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Project.sol#L710

for (uint256 i = 0; i < _length; i++) _alerts[i] = _self.alerts[i];

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/libraries/Tasks.sol#L181

for example, use ++i instead of i++

(3) It Costs More Gas To Initialize Variables To Zero Than To Let The Default Of Zero Be Applied

Severity: Gas Optimizations

Proof Of Concept

for (uint256 i = 0; i < _communities[_communityID].memberCount; i++) {

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Community.sol#L624

for (uint256 i = 0; i < _length; i++) {

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/HomeFiProxy.sol#L87

for (uint256 i = 0; i < _length; i++) {

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/HomeFiProxy.sol#L136

for (uint256 i = 0; i < _length; i++) {

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Project.sol#L248

for (uint256 i = 0; i < _length; i++) {

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Project.sol#L311

for (uint256 i = 0; i < _length; i++) {

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Project.sol#L322

(4) Using > 0 Costs More Gas Than != 0 When Used On A Uint In A Require() Statement

Severity: Gas Optimizations

This change saves 6 gas per instance

Proof Of Concept

require(_repayAmount > 0, "Community::!repay");

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Community.sol#L764

require(_cost > 0, "Project::!value>0");

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Project.sol#L195

(5) Multiple Address Mappings Can Be Combined Into A Single Mapping Of An Address To A Struct, Where Appropriate

Severity: Gas Optimizations

Saves a storage slot for the mapping. Depending on the circumstances and sizes of types, can avoid a Gsset (20000 gas) per mapping combined. Reads and subsequent writes can also be cheaper when a function requires both values and they both fit in the same storage slot.

Proof Of Concept

mapping(address => uint256) public override projectPublished; mapping(address => mapping(bytes32 => bool)) public override approvedHashes;

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Community.sol#L59

mapping(address => uint256) public override projectTokenId; mapping(address => address) public override wrappedToken;

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/HomeFi.sol#L64

(6) Multiplication/division By Two Should Use Bit Shifting

Severity: Gas Optimizations

<x> * 2 is equivalent to <x> << 1 and <x> / 2 is the same as <x> >> 1. The MUL and DIV opcodes cost 5 gas, whereas SHL and SHR only cost 3 gas

Proof Of Concept

_communityProject.lastTimestamp) / 86400; // 24*60*60

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Community.sol#L686

(7) <x> += <y> Costs More Gas Than <x> = <x> + <y> For State Variables

Severity: Gas Optimizations

Proof Of Concept

.totalLent += _amountToProject;

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Community.sol#L423

.lentAmount += _lendingAmount;

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Community.sol#L435

.totalLent += _amountToProject;

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Community.sol#L423

.lentAmount += _lendingAmount;

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Community.sol#L435

_interest -= _repayAmount;

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Community.sol#L798

projectCount += 1;

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/HomeFi.sol#L289

hashChangeNonce += 1;

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Project.sol#L179

_taskCount += 1;

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Project.sol#L250

hashChangeNonce += 1;

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Project.sol#L290

totalAllocated -= _withdrawDifference;

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Project.sol#L431

totalAllocated += _newCost - _taskCost;

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Project.sol#L440

totalAllocated -= _taskCost;

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Project.sol#L456

totalAllocated -= _withdrawDifference;

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Project.sol#L431

totalAllocated += _newCost - _taskCost;

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Project.sol#L440

totalAllocated -= _taskCost;

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Project.sol#L456

totalAllocated -= _withdrawDifference;

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Project.sol#L431

totalAllocated += _newCost - _taskCost;

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Project.sol#L440

totalAllocated -= _taskCost;

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Project.sol#L456

_costToAllocate -= _taskCost;

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Project.sol#L616

_costToAllocate -= _taskCost;

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Project.sol#L616

_cost += tasks[_taskID].cost;

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Project.sol#L711

totalLent -= _amount;

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Project.sol#L772

v += 27;

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/libraries/SignatureDecoder.sol#L83

(8) Using Private Rather Than Public For Constants, Saves Gas

Severity: Gas Optimizations

If needed, the value can be read from the verified contract source code. Savings are due to the compiler not having to create non-payable getter functions for deployment calldata, and not adding another entry to the method ID table

Proof Of Concept

uint256 public constant override VERSION = 25000;

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Project.sol#L60

Set variable to private.

(9) Help The Optimizer By Saving A Storage Variableโ€™s Reference Instead Of Repeatedly Fetching It

Severity: Gas Optimizations

To help the optimizer, declare a storage type variable and use it instead of repeatedly fetching the reference in a map or an array. The effect can be quite significant. As an example, instead of repeatedly calling someMap[someIndex], save its reference like this: SomeStruct storage someStruct = someMap[someIndex] and use it.

Proof Of Concept

CommunityStruct storage _community = _communities[communityCount];

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Community.sol#L143

Dispute storage _dispute = disputes[disputeCount];

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Disputes.sol#L112

cost = tasks[id].cost;

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Project.sol#L553

subcontractor = tasks[id].subcontractor;

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Project.sol#L554

state = tasks[id].state;

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Project.sol#L555

cost = tasks[id].cost;

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Project.sol#L553

subcontractor = tasks[id].subcontractor;

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Project.sol#L554

state = tasks[id].state;

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Project.sol#L555

cost = tasks[id].cost;

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Project.sol#L553

subcontractor = tasks[id].subcontractor;

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Project.sol#L554

state = tasks[id].state;

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Project.sol#L555

(10) ++i/i++ Should Be Unchecked{++i}/unchecked{i++} When It Is Not Possible For Them To Overflow, As Is The Case When Used In For- And While-loops

Severity: Gas Optimizations

The unchecked keyword is new in solidity version 0.8.0, so this only applies to that version or higher, which these instances are. This saves 30-40 gas PER LOOP

Proof Of Concept

for (uint256 i = 0; i < _communities[_communityID].memberCount; i++) {

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Community.sol#L624

for (uint256 i = 0; i < _length; i++) {

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/HomeFiProxy.sol#L87

for (uint256 i = 0; i < _length; i++) {

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/HomeFiProxy.sol#L136

for (uint256 i = 0; i < _length; i++) {

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Project.sol#L248

for (uint256 i = 0; i < _length; i++) {

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Project.sol#L311

for (uint256 i = 0; i < _length; i++) {

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Project.sol#L322

for (; i < _changeOrderedTask.length; i++) {

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Project.sol#L603

for (++j; j <= taskCount; j++) {

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Project.sol#L650

for (; i < _changeOrderedTask.length; i++) {

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Project.sol#L603

for (++j; j <= taskCount; j++) {

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Project.sol#L650

for (uint256 _taskID = 1; _taskID <= _length; _taskID++) {

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Project.sol#L710

(11) Using Bools For Storage Incurs Overhead

Severity: Gas Optimizations

booleans are more expensive than uint256 or any type that takes up a full word because each write operation emits an extra SLOAD to first read the slot's contents, replace the bits taken up by the boolean, and then write back. This is the compiler's defense against contract upgrades and pointer aliasing, and it cannot be disabled.

Proof Of Concept

bool public override restrictedToAdmin;

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Community.sol#L55

mapping(address => mapping(bytes32 => bool)) public override approvedHashes;

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Community.sol#L61

bool public override restrictedToAdmin;

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Community.sol#L55

mapping(address => mapping(bytes32 => bool)) public override approvedHashes;

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Community.sol#L61

bool public override addrSet;

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/HomeFi.sol#L50

mapping(address => bool) internal contractsActive;

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/HomeFiProxy.sol#L30

bool public override contractorConfirmed;

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Project.sol#L68

bool public override contractorDelegated;

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Project.sol#L78

mapping(address => mapping(bytes32 => bool)) public override approvedHashes;

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Project.sol#L84

bool public override contractorConfirmed;

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Project.sol#L68

bool public override contractorDelegated;

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Project.sol#L78

mapping(address => mapping(bytes32 => bool)) public override approvedHashes;

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Project.sol#L84

bool public override contractorConfirmed;

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Project.sol#L68

bool public override contractorDelegated;

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Project.sol#L78

mapping(address => mapping(bytes32 => bool)) public override approvedHashes;

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/Project.sol#L84

mapping(uint256 => bool) alerts;

https://github.com/code-423n4/2022-08-rigor/tree/main/contracts/libraries/Tasks.sol#L16

AuditHub

A portfolio for auditors, a security profile for protocols, a hub for web3 security.

Built bymalatrax ยฉ 2024

Auditors

Browse

Contests

Browse

Get in touch

ContactTwitter