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
Rank: 91/133
Findings: 2
Award: $62.34
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: Lambda
Also found by: 0x1f8b, 0x52, 0xA5DF, 0xNazgul, 0xNineDec, 0xSmartContract, 0xSolus, 0xf15ers, 0xkatana, 0xsolstars, 8olidity, Aymen0909, Bahurum, Bnke0x0, CertoraInc, Chom, CodingNameKiki, Deivitto, Dravee, ElKu, Extropy, Funen, GalloDaSballo, Guardian, IllIllI, JC, Jujic, MEP, Noah3o6, ReyAdmirado, Rohan16, Rolezn, Ruhum, Sm4rty, SooYa, Soosh, Throne6g, TomJ, Tomio, TrungOre, Waze, Yiko, _Adam, __141345__, a12jmx, ajtra, ak1, arcoun, asutorufos, ayeslick, benbaessler, berndartmueller, bin2chen, bobirichman, brgltd, bulej93, byndooa, c3phas, codexploder, cryptonue, cryptphi, defsec, delfin454000, dipp, djxploit, erictee, exd0tpy, fatherOfBlocks, gogo, hake, hansfriese, horsefacts, hyh, ignacio, indijanc, joestakey, kaden, mics, minhquanym, neumo, obront, oyc_109, p_crypt0, pfapostol, poirots, rbserver, robee, rokinot, rotcivegaf, sach1r0, saian, samruna, saneryee, scaraven, sikorico, simon135, sseefried, supernova
40.6216 USDC - $40.62
_decimals = decimals_; communityContract = _communityContract;
underlying = _underlying; homeFi = _homeFi;
underlying = _underlying;
_clone = ClonesUpgradeable.clone(underlying);
homeFi = IHomeFi(_homeFi);
treasury = _treasury; lenderFee = _lenderFee; // the percentage must be multiplied with 10 tokenCurrency1 = _tokenCurrency1; tokenCurrency2 = _tokenCurrency2; tokenCurrency3 = _tokenCurrency3; trustedForwarder = _forwarder;
projectFactoryInstance = IProjectFactory(_projectFactory); communityContract = _communityContract; disputesContract = _disputesContract; wrappedToken[tokenCurrency1] = _hTokenCurrency1; wrappedToken[tokenCurrency2] = _hTokenCurrency2; wrappedToken[tokenCurrency3] = _hTokenCurrency3; addrSet = true;
admin = _newAdmin;
treasury = _newTreasury;
lenderFee = _newLenderFee;
trustedForwarder = _newForwarder;
builder = _sender;
contractorDelegated = _bool;
totalLent -= _amount;
function initialize( address _communityContract, string memory name_, string memory symbol_, uint8 decimals_ ) external override initializer {
function initialize(address _underlying, address _homeFi) external override initializer nonZero(_underlying) nonZero(_homeFi) {
// SPDX-License-Identifier: MIT
// SPDX-License-Identifier: MIT
// SPDX-License-Identifier: MIT
// SPDX-License-Identifier: MIT
// SPDX-License-Identifier: MIT
// SPDX-License-Identifier: MIT
// SPDX-License-Identifier: MIT
// SPDX-License-Identifier: MIT
// SPDX-License-Identifier: MIT
contract DebtToken is IDebtToken, ERC20Upgradeable {
contract ProjectFactory is IProjectFactory, Initializable, ERC2771ContextUpgradeable {
contract HomeFiProxy is OwnableUpgradeable {
contract Disputes is IDisputes, ReentrancyGuardUpgradeable, ERC2771ContextUpgradeable {
contract HomeFi is IHomeFi, ReentrancyGuardUpgradeable, ERC721URIStorageUpgradeable, ERC2771ContextUpgradeable {
contract Project is IProject, ReentrancyGuardUpgradeable, ERC2771ContextUpgradeable {
contract Community is ICommunity, PausableUpgradeable, ReentrancyGuardUpgradeable, ERC2771ContextUpgradeable {
return _decimals;
return IHomeFi(homeFi).isTrustedForwarder(_forwarder);
return contractsActive[_address];
return contractAddress[_contractName];
return homeFi.isTrustedForwarder(_forwarder);
return _changeOrderedTask;
return _members;
if (messageSignatures.length % 65 != 0) {
if (v != 27 && v != 28) {
(_projectInstance.lenderFee() + 1000);
string.concat()
to be used instead of abi.encodePacked(<str>,<str>)
):-pragma solidity 0.8.6;
bool _exceedLimit;
`function decimals() public view virtual override returns (uint8) { return _decimals; }
/*******************************************************************************
/// @notice blocked implementation function transferFrom( address, /* _sender / address, / _recipient / uint256 / _amount */ ) public pure override(ERC20Upgradeable, IERC20Upgradeable) returns (bool) { revert("DebtToken::blocked"); }
/// @notice blocked implementation function transfer( address, /* recipient / uint256 / amount */ ) public pure override(ERC20Upgradeable, IERC20Upgradeable) returns (bool) { revert("DebtToken::blocked"); }`
function isTrustedForwarder(address _forwarder) public view override(ERC2771ContextUpgradeable, IProjectFactory) returns (bool) {
function assertMember( address _project, uint256 _taskID, address _address ) public view override {
function isTrustedForwarder(address _forwarder) public view override(ERC2771ContextUpgradeable, IDisputes) returns (bool) {
` function validCurrency(address _currency) public view override { // _currency must be one of HomeFi supported currencies require( _currency == tokenCurrency1 || _currency == tokenCurrency2 || _currency == tokenCurrency3, "HomeFi::!Currency" ); }
/// @inheritdoc IHomeFi function isTrustedForwarder(address _forwarder) public view override(ERC2771ContextUpgradeable, IHomeFi) returns (bool) { return trustedForwarder == _forwarder; }`
` function projectCost() public view override returns (uint256 _cost) { // Local instance of taskCount. To save gas. uint256 _length = taskCount;
// Iterate over all tasks to sum their cost for (uint256 _taskID = 1; _taskID <= _length; _taskID++) { _cost += tasks[_taskID].cost; }
}
/// @inheritdoc IProject function getAlerts(uint256 _taskID) public view override returns (bool[3] memory _alerts) { return tasks[_taskID].getAlerts(); }
/// @inheritdoc IProject function isTrustedForwarder(address _forwarder) public view override(ERC2771ContextUpgradeable, IProject) returns (bool) { return homeFi.isTrustedForwarder(_forwarder); }`
#0 - zgorizzo69
2022-08-08T18:42:06Z
L-01 If you look at the modifiers lot of them are actually check against address(0) L-03 why ? L-04 only applicable for base contracts the mentioned contracts doesn't inherit from base class that is missing a gap N-5 please note that not all the functions can be made external as they are part of overridden base functions N-4 What has it to do with security and gas optimization !? N-3 we need to be able to decode so using string concat is not ideal N-1 none of these functions returned a named return variable
🌟 Selected for report: c3phas
Also found by: 0x040, 0x1f8b, 0xA5DF, 0xNazgul, 0xSmartContract, 0xSolus, 0xc0ffEE, 0xkatana, 0xsam, 8olidity, Aymen0909, Bnke0x0, CertoraInc, Chinmay, Chom, CodingNameKiki, Deivitto, Dravee, ElKu, Extropy, Fitraldys, Funen, GalloDaSballo, Guardian, IllIllI, JC, Lambda, MEP, Metatron, MiloTruck, Noah3o6, NoamYakov, PaludoX0, ReyAdmirado, Rohan16, Rolezn, Ruhum, Sm4rty, SooYa, TomJ, Tomio, Waze, _Adam, __141345__, a12jmx, ajtra, ak1, apostle0x01, asutorufos, ballx, benbaessler, bharg4v, bobirichman, brgltd, cryptonue, defsec, delfin454000, dharma09, djxploit, durianSausage, eierina, erictee, fatherOfBlocks, gerdusx, gogo, hake, hyh, ignacio, jag, kaden, kyteg, lucacez, mics, minhquanym, oyc_109, pfapostol, rbserver, ret2basic, robee, rokinot, sach1r0, saian, samruna, scaraven, sikorico, simon135, supernova, teddav, tofunmi, zeesaw
21.7232 USDC - $21.72
uint8 internal _decimals;
address public override communityContract;
' /// @inheritdoc IProjectFactory address public override underlying; /// @inheritdoc IProjectFactory address public override homeFi;'
` /// @notice Address of proxy admin ProxyAdmin public proxyAdmin;
/// @notice bytes2 array of upgradable contracts initials
bytes2[] public allContractNames;`
` /// @inheritdoc IDisputes IHomeFi public override homeFi; /// @inheritdoc IDisputes uint256 public override disputeCount; //starts from 0`
`/// @inheritdoc IHomeFi address public override tokenCurrency1; /// @inheritdoc IHomeFi address public override tokenCurrency2; /// @inheritdoc IHomeFi address public override tokenCurrency3; /// @inheritdoc IHomeFi IProjectFactory public override projectFactoryInstance; /// @inheritdoc IHomeFi address public override disputesContract; /// @inheritdoc IHomeFi address public override communityContract; /// @inheritdoc IHomeFi bool public override addrSet; /// @inheritdoc IHomeFi address public override admin; /// @inheritdoc IHomeFi address public override treasury; /// @inheritdoc IHomeFi uint256 public override lenderFee; /// @inheritdoc IHomeFi uint256 public override projectCount; /// @inheritdoc IHomeFi address public override trustedForwarder;`
` /// @inheritdoc IProject IHomeFi public override homeFi; /// @inheritdoc IProject IDebtToken public override currency; /// @inheritdoc IProject uint256 public override lenderFee; /// @inheritdoc IProject address public override builder; /// @inheritdoc IProject uint256 public constant override VERSION = 25000; /******************************************************************************* * ---------------------VARIABLE PUBLIC STORED PROPERTIES--------------------- * *******************************************************************************/ /// @inheritdoc IProject address public override contractor; /// @inheritdoc IProject bool public override contractorConfirmed; /// @inheritdoc IProject uint256 public override hashChangeNonce; /// @inheritdoc IProject uint256 public override totalLent; /// @inheritdoc IProject uint256 public override totalAllocated; /// @inheritdoc IProject uint256 public override taskCount; /// @inheritdoc IProject bool public override contractorDelegated; /// @inheritdoc IProject uint256 public override lastAllocatedTask; /// @inheritdoc IProject uint256 public override lastAllocatedChangeOrderTask;`
`address internal tokenCurrency1; address internal tokenCurrency2; address internal tokenCurrency3;`
` IHomeFi public override homeFi; /******************************************************************************* * ---------------------VARIABLE PUBLIC STORED PROPERTIES--------------------- * *******************************************************************************/ /// @inheritdoc ICommunity bool public override restrictedToAdmin; /// @inheritdoc ICommunity uint256 public override communityCount;`
x = x + y
is cheaper than x += y
:-totalAllocated -= _withdrawDifference;
totalAllocated -= _taskCost;
_costToAllocate -= _taskCost;
_costToAllocate -= _taskCost;
totalLent -= _amount;
_interest -= _repayAmount;
totalAllocated += _newCost - _taskCost;
_cost += tasks[_taskID].cost;
.totalLent += _amountToProject;
lentAmount += _lendingAmount;
for (; i < _changeOrderedTask.length; i++) {
for (uint256 i = 0; i < _length; i++) {
for (uint256 i = 0; i < _length; i++) {
for (uint256 i = 0; i < _length; i++) {
for (uint256 i = 0; i < _length; i++) {
for (uint256 i = 0; i < _length; i++) {
for (uint256 _taskID = 1; _taskID <= _length; _taskID++) {
for (; i < _changeOrderedTask.length; i++) {
_loopCount++;
for (++j; j <= taskCount; j++) {
_loopCount++;
for (uint256 _taskID = 1; _taskID <= _length; _taskID++) {
communityCount++;
_community.publishNonce = ++_community.publishNonce;
for (uint256 i = 0; i < _communities[_communityID].memberCount; i++) {
for (uint256 i = 0; i < _length; i++) _alerts[i] = _self.alerts[i];
return _decimals;
return IHomeFi(homeFi).isTrustedForwarder(_forwarder);
return contractsActive[_address];
return contractAddress[_contractName];
return homeFi.isTrustedForwarder(_forwarder);
return _changeOrderedTask;
return _members;
> 0
costs more gas than != 0
when used on a uint in a require()
statement :-require( _actionType > 0 && _actionType <= uint8(ActionType.TaskPay), "Disputes::!ActionType" );
require(_cost > 0, "Project::!value>0");
require(_repayAmount > 0, "Community::!repay");
for (uint256 i = 0; i < _length; i++) {
for (uint256 i = 0; i < _length; i++) {
for (uint256 i = 0; i < _length; i++) {
for (uint256 i = 0; i < _length; i++) {
for (uint256 i = 0; i < _length; i++) {
for (uint256 i = 0; i < _communities[_communityID].memberCount; i++) {
for (uint256 i = 0; i < _length; i++) _alerts[i] = _self.alerts[i];
lastAllocatedChangeOrderTask = 0;
_interest = 0;
require()
statements that use && saves gas :-require( _disputeID < disputeCount && disputes[_disputeID].status == Status.Active, "Disputes::!Resolvable" );
require( _actionType > 0 && _actionType <= uint8(ActionType.TaskPay), "Disputes::!ActionType" );
require( _sender == builder || _sender == homeFi.communityContract(), "Project::!Builder&&!Community" );
require( _lendingNeeded >= _communityProject.totalLent && _lendingNeeded <= IProject(_project).projectCost(), "Community::invalid lending" );
uint8 internal _decimals;
uint8 decimals_
function decimals() public view virtual override returns (uint8) {
uint8 _actionType,
_actionType > 0 && _actionType <= uint8(ActionType.TaskPay),
uint8 v
uint8 v,
require(_projectAddress == address(this), "Project::!projectAddress");
require( communityContract == _msgSender(), "DebtToken::!CommunityContract" );
require(_communityContract != address(0), "DebtToken::0 address");
require(_address != address(0), "PF::0 address");
require( _msgSender() == IHomeFi(homeFi).admin(), "ProjectFactory::!Owner" );
require(_msgSender() == homeFi, "PF::!HomeFiContract");
require(_address != address(0), "Proxy::0 address");
require(_length == _implementations.length, "Proxy::Lengths !match");
require( contractAddress[_contractName] == address(0), "Proxy::Name !OK" )
require(_length == _contractAddresses.length, "Proxy::Lengths !match");
require(_address != address(0), "Disputes::0 address");
require(homeFi.admin() == _msgSender(), "Disputes::!Admin");
require(homeFi.isProjectExist(_msgSender()), "Disputes::!Project");
require( _disputeID < disputeCount && disputes[_disputeID].status == Status.Active, "Disputes::!Resolvable" );
require( _actionType > 0 && _actionType <= uint8(ActionType.TaskPay), "Disputes::!ActionType" );
require(_result, "Disputes::!Member");
require(admin == _msgSender(), "HomeFi::!Admin");
require(_address != address(0), "HomeFi::0 address");
require(_oldAddress != _newAddress, "HomeFi::!Change");
require(!addrSet, "HomeFi::Set");
require(lenderFee != _newLenderFee, "HomeFi::!Change");
require( _currency == tokenCurrency1 || _currency == tokenCurrency2 || _currency == tokenCurrency3, "HomeFi::!Currency" );
require(!contractorConfirmed, "Project::GC accepted");
require(_projectAddress == address(this), "Project::!projectAddress");
require(_contractor != address(0), "Project::0 address");
`require(_msgSender() == builder, "Project::!B");
// Revert if contract not assigned require(contractor != address(0), "Project::0 address");`
require(_nonce == hashChangeNonce, "Project::!Nonce");
`require( _sender == builder || _sender == homeFi.communityContract(), "Project::!Builder&&!Community" );
// Revert if try to lend 0 require(_cost > 0, "Project::!value>0"); // Revert if try to lend more than project cost uint256 _newTotalLent = totalLent + _cost; require( projectCost() >= uint256(_newTotalLent), "Project::value>required" );`
` require(_taskCount == taskCount, "Project::!taskCount");
// Revert if decoded project address does not match this contract. Indicating incorrect _data. require(_projectAddress == address(this), "Project::!projectAddress"); // Revert if IPFS hash array length is not equal to task cost array length. uint256 _length = _hash.length; require(_length == _taskCosts.length, "Project::Lengths !match");`
require( require(_nonce == hashChangeNonce, "Project::!Nonce");
require( _msgSender() == builder || _msgSender() == contractor, "Project::!Builder||!GC" );
require(_length == _scList.length, "Project::Lengths !match");
require(_projectAddress == address(this), "Project::!Project");
require(tasks[_taskID].getState() == 3, "Project::!Complete");
`require(_project == address(this), "Project::!projectAddress");
if (_task == 0) { // Revet if sender is not builder or contractor require( signer == builder || signer == contractor, "Project::!(GC||Builder)" ); } else { // Revet if sender is not builder, contractor or task's subcontractor require( signer == builder || signer == contractor || signer == tasks[_task].subcontractor, "Project::!(GC||Builder||SC)" ); if (signer == tasks[_task].subcontractor) { // If sender is task's subcontractor, revert if invitation is not accepted. require(getAlerts(_task)[2], "Project::!SCConfirmed"); }`
require(_sc != address(0), "Project::0 address");
require( _recoveredSignature == _address || approvedHashes[_address][_hash], "Project::invalid signature" );
require( ((_amount / 1000) * 1000) == _amount, "Project::Precision>=1000" );
require(_self.state == TaskStatus.Inactive, "Task::active");
require(_self.state == TaskStatus.Active, "Task::!Active");
require( _self.alerts[uint256(Lifecycle.TaskAllocated)], "Task::!funded" );
require(_self.subcontractor == _sc, "Task::!SC");}
` require(_address != address(0), "Community::0 address"); _; }
modifier onlyHomeFiAdmin() { // Revert if sender is not homeFi admin require(_msgSender() == homeFi.admin(), "Community::!admin"); _; }
modifier isPublishedToCommunity(uint256 _communityID, address _project) { // Revert if _project is not published to _communityID require( projectPublished[_project] == _communityID, "Community::!published" ); _; }
modifier onlyProjectBuilder(address _project) { // Revert if sender is not _project builder require( _msgSender() == IProject(_project).builder(), "Community::!Builder" );`
require( !restrictedToAdmin || _sender == homeFi.admin(), "Community::!admin" );
require( _communities[_communityID].owner == _msgSender(), "Community::!owner" );
require( !_community.isMember[_newMemberAddr], "Community::Member Exists" );
`require( _publishNonce == _community.publishNonce, "Community::invalid publishNonce" );
// Reverts if _project not originated from HomeFi require(homeFi.isProjectExist(_project), "Community::Project !Exists"); // Local instance of variables. For saving gas. IProject _projectInstance = IProject(_project); address _builder = _projectInstance.builder(); // Revert if project builder is not community member require(_community.isMember[_builder], "Community::!Member"); // Revert if project currency does not match community currency require( _projectInstance.currency() == _community.currency, "Community::!Currency" );`
require( !_communityProject.publishFeePaid, "Community::publish fee paid" );
`require( _communityProject.publishFeePaid, "Community::publish fee !paid" );
// Revert if _lendingNeeded is more than projectCost or less than what is already lent require( _lendingNeeded >= _communityProject.totalLent && _lendingNeeded <= IProject(_project).projectCost(), "Community::invalid lending" );`
require( _sender == _communities[_communityID].owner, "Community::!owner" );
require( _amountToProject <= _communities[_communityID] .projectDetails[_project] .lendingNeeded - _communities[_communityID] .projectDetails[_project] .totalLent, "Community::lending>needed" );
require( _msgSender() == _communities[_communityID].owner, "Community::!Owner" );
` require(_builder == _projectInstance.builder(), "Community::!Builder");
// Revert if decoded _communityID's owner is not decoded _lender require( _lender == _communities[_communityID].owner, "Community::!Owner" );`
require(!restrictedToAdmin, "Community::restricted");
require(restrictedToAdmin, "Community::!restricted");
require(_repayAmount > 0, "Community::!repay");
require(_lentAndInterest >= _repayAmount, "Community::!Liquid");
require( _recoveredSignature == _address || approvedHashes[_address][_hash], "Community::invalid signature" );
pragma solidity 0.8.6;
pragma solidity 0.8.6;
pragma solidity 0.8.6;
pragma solidity 0.8.6;
pragma solidity 0.8.6;
pragma solidity 0.8.6;
pragma solidity 0.8.6;
pragma solidity 0.8.6;
pragma solidity 0.8.6;
`function mint(address _to, uint256 _total) external override onlyCommunityContract { _mint(_to, _total); }
/// @inheritdoc IDebtToken function burn(address _to, uint256 _total) external override onlyCommunityContract { _burn(_to, _total); }`
function addNewContract(bytes2 _contractName, address _contractAddress) external onlyOwner {
function upgradeMultipleImplementations( bytes2[] calldata _contractNames, address[] calldata _contractAddresses ) external onlyOwner {
function changeProxyAdminOwner(address _newAdmin) external onlyOwner nonZero(_newAdmin) {
function raiseDispute(bytes calldata _data, bytes calldata _signature) external override onlyProject {
function resolveDispute( uint256 _disputeID, bytes calldata _judgement, bool _ratify ) external override onlyAdmin nonReentrant resolvable(_disputeID) {
function setAddr( address _projectFactory, address _communityContract, address _disputesContract, address _hTokenCurrency1, address _hTokenCurrency2, address _hTokenCurrency3 ) external override onlyAdmin nonZero(_projectFactory) nonZero(_communityContract) nonZero(_disputesContract) nonZero(_hTokenCurrency1) nonZero(_hTokenCurrency2) nonZero(_hTokenCurrency3) {
` function replaceAdmin(address _newAdmin) external override onlyAdmin nonZero(_newAdmin) noChange(admin, _newAdmin) { // Replace admin admin = _newAdmin;
emit AdminReplaced(_newAdmin);
}
/// @inheritdoc IHomeFi function replaceTreasury(address _newTreasury) external override onlyAdmin nonZero(_newTreasury) noChange(treasury, _newTreasury) { // Replace treasury treasury = _newTreasury;
emit TreasuryReplaced(_newTreasury);
}
/// @inheritdoc IHomeFi function replaceLenderFee(uint256 _newLenderFee) external override onlyAdmin {`
function setTrustedForwarder(address _newForwarder) external override onlyAdmin noChange(trustedForwarder, _newForwarder) {
` function unpublishProject(uint256 _communityID, address _project) external override whenNotPaused isPublishedToCommunity(_communityID, _project) onlyProjectBuilder(_project) { // Call internal function to unpublish project _unpublishProject(_project); }
/// @inheritdoc ICommunity function payPublishFee(uint256 _communityID, address _project) external override nonReentrant whenNotPaused isPublishedToCommunity(_communityID, _project) onlyProjectBuilder(_project) {`
function toggleLendingNeeded( uint256 _communityID, address _project, uint256 _lendingNeeded ) external override whenNotPaused isPublishedToCommunity(_communityID, _project) onlyProjectBuilder(_project) {
function repayLender( uint256 _communityID, address _project, uint256 _repayAmount ) external virtual override nonReentrant whenNotPaused onlyProjectBuilder(_project) {
` function restrictToAdmin() external override onlyHomeFiAdmin { // Revert if already restricted to admin require(!restrictedToAdmin, "Community::restricted");
// Disable community creation for non admins restrictedToAdmin = true; emit RestrictedToAdmin(_msgSender());
}
/// @inheritdoc ICommunity function unrestrictToAdmin() external override onlyHomeFiAdmin { // Revert if already unrestricted to admin require(restrictedToAdmin, "Community::!restricted");
// Allow community creation for all restrictedToAdmin = false; emit UnrestrictedToAdmin(_msgSender());
}
/// @inheritdoc ICommunity function pause() external override onlyHomeFiAdmin { _pause(); }
/// @inheritdoc ICommunity function unpause() external override onlyHomeFiAdmin { _unpause(); }`
` function setComplete(Task storage _self) internal onlyActive(_self) onlyFunded(_self) { // State/ Lifecycle // _self.state = TaskStatus.Complete; }
// Subcontractor Joining //
/**
/**
`function decimals() public view virtual override returns (uint8) { return _decimals; }
/*******************************************************************************
/// @notice blocked implementation function transferFrom( address, /* _sender / address, / _recipient / uint256 / _amount */ ) public pure override(ERC20Upgradeable, IERC20Upgradeable) returns (bool) { revert("DebtToken::blocked"); }
/// @notice blocked implementation function transfer( address, /* recipient / uint256 / amount */ ) public pure override(ERC20Upgradeable, IERC20Upgradeable) returns (bool) { revert("DebtToken::blocked"); }`
function isTrustedForwarder(address _forwarder) public view override(ERC2771ContextUpgradeable, IProjectFactory) returns (bool) {
function assertMember( address _project, uint256 _taskID, address _address ) public view override {
function isTrustedForwarder(address _forwarder) public view override(ERC2771ContextUpgradeable, IDisputes) returns (bool) {
` function validCurrency(address _currency) public view override { // _currency must be one of HomeFi supported currencies require( _currency == tokenCurrency1 || _currency == tokenCurrency2 || _currency == tokenCurrency3, "HomeFi::!Currency" ); }
/// @inheritdoc IHomeFi function isTrustedForwarder(address _forwarder) public view override(ERC2771ContextUpgradeable, IHomeFi) returns (bool) { return trustedForwarder == _forwarder; }`
` function projectCost() public view override returns (uint256 _cost) { // Local instance of taskCount. To save gas. uint256 _length = taskCount;
// Iterate over all tasks to sum their cost for (uint256 _taskID = 1; _taskID <= _length; _taskID++) { _cost += tasks[_taskID].cost; }
}
/// @inheritdoc IProject function getAlerts(uint256 _taskID) public view override returns (bool[3] memory _alerts) { return tasks[_taskID].getAlerts(); }
/// @inheritdoc IProject function isTrustedForwarder(address _forwarder) public view override(ERC2771ContextUpgradeable, IProject) returns (bool) { return homeFi.isTrustedForwarder(_forwarder); }`
mapping(address => uint256) public override projectTokenId; /// @inheritdoc IHomeFi mapping(address => address) public override wrappedToken;
mapping(address => uint256) public override projectPublished; /// @inheritdoc ICommunity mapping(address => mapping(bytes32 => bool)) public override approvedHashes;
#0 - zgorizzo69
2022-08-08T16:17:54Z
very extensive gas optimization report thanks