Platform: Code4rena
Start Date: 16/02/2023
Pot Size: $144,750 USDC
Total HM: 17
Participants: 154
Period: 19 days
Judge: Trust
Total Solo HM: 5
Id: 216
League: ETH
Rank: 47/154
Findings: 2
Award: $204.11
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: GalloDaSballo
Also found by: 0xBeirao, 0xRobocop, AkshaySrivastav, KingNFT, MiloTruck, PaludoX0, bin2chen, hansfriese, imare, kaden
142.8544 USDC - $142.85
https://github.com/code-423n4/2023-02-ethos/blob/73687f32b934c9d697b97745356cdf8a1f264955/Ethos-Core/contracts/ActivePool.sol#L282 https://github.com/code-423n4/2023-02-ethos/blob/73687f32b934c9d697b97745356cdf8a1f264955/Ethos-Core/contracts/ActivePool.sol#L302
In ActivePool#_rebalance()
after the code determines the netAssetMovement
value for withdrawing the wrong value is used with the yield generator withdraw
method.
In rebalancing when withdrawing from yield generator the ActivePool
contract extracts less collateral asset then calculated. In case of profit distribution this can possible result in a unintended revert in case the contract entire balance end with less collateral that we can distribute.
In this line we are using the wrong value to withdraw assets from the yield generator. The correct value to use with the withdraw functions is the value of shares and not assets:
A possible revert can happen when the ActivePool
ends having less collateral asset in its balance then calculated for splitting on the next line:
Resulting in a unintended revert
Manual review
Convert calculated asset value to shares and then withdraw
} else if (vars.netAssetMovement < 0) { + uint256 shares = IERC4626(yieldGenerator[_collateral]).convertToShares(uint256(-vars.netAssetMovement)); IERC4626(yieldGenerator[_collateral]).withdraw(shares, address(this), address(this)); }
#0 - c4-judge
2023-03-08T15:44:00Z
trust1995 marked the issue as duplicate of #747
#1 - c4-judge
2023-03-08T15:44:04Z
trust1995 marked the issue as satisfactory
🌟 Selected for report: GalloDaSballo
Also found by: 0x3b, 0xAgro, 0xSmartContract, 0xTheC0der, 0xackermann, 0xnev, 0xsomeone, ABA, BRONZEDISC, Bjorn_bug, Bnke0x0, Breeje, Co0nan, CodeFoxInc, CodingNameKiki, DadeKuma, DeFiHackLabs, IceBear, Josiah, Kaysoft, Lavishq, MohammedRizwan, PaludoX0, PawelK, Phantasmagoria, Raiders, RaymondFam, Rickard, Rolezn, Sathish9098, SleepingBugs, SuperRayss, UdarTeam, Udsen, Viktor_Cortess, arialblack14, ast3ros, bin2chen, brgltd, btk, catellatech, ch0bu, chaduke, chrisdior4, codeislight, cryptonue, delfin454000, descharre, dontonka, emmac002, fs0c, hacker-dom, hansfriese, imare, lukris02, luxartvinsec, martin, matrix_0wl, peanuts, rbserver, shark, tnevler, trustindistrust, tsvetanovv, vagrant, yongskiws, zzzitron
61.2601 USDC - $61.26
When setting the claim treshold field that is used inside rebalancing there is no verification for the field to trigger any profit distribution.
Other yield parameters are checked for their correct working.
_requireCallerIsBOorTroveMorSP
error is missing the redemptionHelper explanationWhen the require error is triggered its explanation is missing to report that also redemptionHelper
can be the caller of this function:
This method by definition MUST NOT REVERT but if tvlCap
is lower then the current balance()
the version of solidity used will revert the call.
A check before the calculation must be done to prevent reverting the call.
Note: tvlCap
value can be arbitrary changed by the admin
user by calling updateTvlCap
method.
ReaperVaultV2#updateTvlCap
doesn't properly validate the newTvlCapThere is no prevention of setting the total value locked cap to be lower then the current balance.
ReaperBaseStrategyv4#__ReaperBaseStrategy_init
multisigRoles is not verified that role is indeed assignedThe intention of role assignments is not verified and will silently fail when called with an empty or smaller _multisigRoles
array
ReaperBaseStrategyv4#initiateUpgradeCooldown()
should emit an eventThere should be an event emitted when calling this function to signal users to prepare for imminent protocol upgrade
Once the collateral is added with CollateralConfig#initialize
it cannot be removed. There is no functionality that addresses the removal of collateral.
On the main page of Tellor for the oracle there is only mention for the TellorFlex and is not the one that is currently in use for Ethos
protocol.
On optimism network the currently used/deployed TellorCaller seams to be used only by the Ethos protocol and is not supported by the original Tellor developer.
yieldClaimThreshold
in ActivePool#rebalance
is not taking in account token directly sent to the contractWhen profit is finally detected because of the yield generator the token sent directly to the contract are finally taken into account.
A better solution would be to take this token in account earlier by checking the difference in collAmount
and the balance of the contract for the same collateral.
vars.profit = vars.sharesToAssets.sub(vars.currentAllocated); +int256 diff = IERC20(_collateral).balanceOf(address(this)) - collAmount[_collateral]; + +if (diff > 0) { + vars.profit = vars.profit.add(diff); +} + if (vars.profit < yieldClaimThreshold[_collateral]) { vars.profit = 0; }
Note: inhering contract of this abstract contract is also missing the __gap field variable.
#0 - c4-judge
2023-03-09T08:46:51Z
trust1995 marked the issue as grade-b
#1 - c4-sponsor
2023-03-17T23:58:38Z
0xBebis marked the issue as sponsor confirmed