Ethereum Credit Guild - wangxx2026's results

A trust minimized pooled lending protocol.

General Information

Platform: Code4rena

Start Date: 11/12/2023

Pot Size: $90,500 USDC

Total HM: 29

Participants: 127

Period: 17 days

Judge: TrungOre

Total Solo HM: 4

Id: 310

League: ETH

Ethereum Credit Guild

Findings Distribution

Researcher Performance

Rank: 117/127

Findings: 1

Award: $3.05

🌟 Selected for report: 0

🚀 Solo Findings: 0

Awards

3.0466 USDC - $3.05

Labels

bug
3 (High Risk)
satisfactory
sufficient quality report
duplicate-473

External Links

Lines of code

https://github.com/code-423n4/2023-12-ethereumcreditguild/blob/2376d9af792584e3d15ec9c32578daa33bb56b43/src/loan/SurplusGuildMinter.sol#L229 https://github.com/code-423n4/2023-12-ethereumcreditguild/blob/2376d9af792584e3d15ec9c32578daa33bb56b43/src/loan/SurplusGuildMinter.sol#L166 https://github.com/code-423n4/2023-12-ethereumcreditguild/blob/2376d9af792584e3d15ec9c32578daa33bb56b43/src/loan/SurplusGuildMinter.sol#L298

Vulnerability details

Impact

This will result in the guildReward not being fetched properly, and the unstake and updateMintRatio methods not running properly. If unstake does not work properly, the pledged assets will not be redeemed properly, and if updateMintRatio does not work properly, the mintratio will not be updated properly, which will affect the leverage level.

Proof of Concept

The implementation of getRewards is as follows: https://github.com/code-423n4/2023-12-ethereumcreditguild/blob/2376d9af792584e3d15ec9c32578daa33bb56b43/src/loan/SurplusGuildMinter.sol#L216-L290

    function getRewards(
        address user,
        address term
    )
        public
        returns (
            uint256 lastGaugeLoss, // GuildToken.lastGaugeLoss(term)
            UserStake memory userStake, // stake state after execution of getRewards()
            bool slashed // true if the user has been slashed
        )
    {
        bool updateState;
        lastGaugeLoss = GuildToken(guild).lastGaugeLoss(term);
 --->       if (lastGaugeLoss > uint256(userStake.lastGaugeLoss)) { // userStake is not assigned a value, it is just declared in returns. lastGaugeLoss is always 0.
            slashed = true;
        }

        // if the user is not staking, do nothing
--->        userStake = _stakes[user][term]; // The correct way to use it is to use userStake.lastGaugeLoss after this line.
        if (userStake.stakeTime == 0)
            return (lastGaugeLoss, userStake, slashed);
...

            if (slashed) {
--->                guildReward = 0; // guildReward cannot be taken
            }
...


    }

Both unstake and updateMintRatio depend on slashed not being true in order to work properly. If true, unstake won't work and all pledged assets won't be redeemed, and updateMintRatio won't work properly causing mintratio to not be updated properly and affecting leverage levels

Tools Used

Manual Review

After userStake = _stakes[user][term] is assigned, then call the following code:

     if (lastGaugeLoss > uint256(userStake.lastGaugeLoss)) {
            slashed = true;
     }

Assessed type

Context

#0 - c4-pre-sort

2023-12-29T14:45:13Z

0xSorryNotSorry marked the issue as sufficient quality report

#1 - c4-pre-sort

2023-12-29T14:45:32Z

0xSorryNotSorry marked the issue as duplicate of #1164

#2 - c4-judge

2024-01-28T20:10:35Z

Trumpero marked the issue as satisfactory

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