Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gas Optimizations #343

Open
code423n4 opened this issue Aug 6, 2022 · 0 comments
Open

Gas Optimizations #343

code423n4 opened this issue Aug 6, 2022 · 0 comments
Labels

Comments

@code423n4
Copy link
Contributor

  • In Community.sol L393-394, save _projectInstance.lenderFee() in a variable instead of calling it two times.
  • In the contract Community in the function lendToProject, defining two storage variables as CommunityStruct storage community = _communities[_communityID] and ProjectDetails storage project = community.projectDetails[_project] would save gas (limit the scope of some variables to avoid stack too deep). Ex:
function lendToProject(
    uint256 _communityID,
    address _project,
    uint256 _lendingAmount,
    bytes calldata _hash
)
    external
    virtual
    override
    nonReentrant
    whenNotPaused
    isPublishedToCommunity(_communityID, _project)
{
    // Local instance of variable. For saving gas.
    address _sender = _msgSender();

    CommunityStruct storage community = _communities[_communityID];

    // Revert if sender is not community owner.
    // Only community owner can lend.
    require(
        _sender == community.owner,
        "Community::!owner"
    );

    // Local instance of variable. For saving gas.
    IProject _projectInstance = IProject(_project);

    // Calculate lenderFee
    uint256 _lenderFee = (_lendingAmount * _projectInstance.lenderFee()) /
        (_projectInstance.lenderFee() + 1000);

    // Calculate amount going to project. Lending amount - lending fee.
    uint256 _amountToProject = _lendingAmount - _lenderFee;

    ProjectDetails storage project = community.projectDetails[_project];

    // Revert if _amountToProject is not within further investment needed.
    require(
        _amountToProject <= project.lendingNeeded - project.totalLent,
        "Community::lending>needed"
    );

    {
        // Local instance of variable. For saving gas.
        IDebtToken _currency = community.currency;
        IDebtToken _wrappedToken = IDebtToken(
            homeFi.wrappedToken(address(_currency))
        );

        // Update investment in Project
        _projectInstance.lendToProject(_amountToProject);

        // Update total lent by lender
        project.totalLent += _amountToProject;

        // First claim interest if principal lent > 0
        if (
            project.lentAmount > 0
        ) {
            claimInterest(_communityID, _project, _wrappedToken);
        }

        // Increment lent principal
        project.lentAmount += _lendingAmount;

        // Update lastTimestamp
        project.lastTimestamp = block.timestamp;

        // Transfer _lenderFee to HomeFi treasury from lender account
        _currency.safeTransferFrom(_msgSender(), homeFi.treasury(), _lenderFee);

        // Transfer _amountToProject to _project from lender account
        _currency.safeTransferFrom(_msgSender(), _project, _amountToProject);

        // Mint new _lendingAmount amount wrapped token to lender
        _wrappedToken.mint(_sender, _lendingAmount);
    }

    emit LenderLent(_communityID, _project, _sender, _lendingAmount, _hash);
}
  • for loops can be optimized, the most optimized loop is:
for (uint256 i; i < length;) {
    // content
    unchecked {
        ++i;
    }
}

and if the iteration is over an array list, store its length in a variable before the loop instead of computing it at each iteration (same for all other storage variables).
Unoptimized loops appear in Community.sol L624, in HomeFiProxy.sol L87, L136, in Project.sol L248, L311, L322, L368, L603, L650, L710, in Tasks.sol L181.

@code423n4 code423n4 added bug Something isn't working G (Gas Optimization) labels Aug 6, 2022
code423n4 added a commit that referenced this issue Aug 6, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants