Platform: Code4rena
Start Date: 17/02/2022
Pot Size: $75,000 USDC
Total HM: 7
Participants: 23
Period: 7 days
Judge: GalloDaSballo
Total Solo HM: 2
Id: 92
League: ETH
Rank: 3/23
Findings: 3
Award: $10,027.56
🌟 Selected for report: 1
🚀 Solo Findings: 1
3049.5907 USDC - $3,049.59
Currently fees can be set as high as 100%, may consider a lower max fee to reduce rug risk
src/modules/TurboClerk.sol:38: require(newDefaultFeePercentage <= 1e18, "FEE_TOO_HIGH"); src/modules/TurboClerk.sol:72: require(newFeePercentage <= 1e18, "FEE_TOO_HIGH"); src/modules/TurboClerk.sol:90: require(newFeePercentage <= 1e18, "FEE_TOO_HIGH");
The id of first TurboSafe is 0 (id = safes.length - 1 = 1 - 1 = 0
), which is invalid.
require(getSafeId[safe] != 0, "INVALID_SAFE");
src/TurboMaster.sol:208: require(getSafeId[safe] != 0, "INVALID_SAFE"); src/TurboMaster.sol:258: require(getSafeId[safe] != 0, "INVALID_SAFE"); src/TurboMaster.sol:288: require(getSafeId[safe] != 0, "INVALID_SAFE");
It is impossible to set effective custom fee to becuase it is only used if customFeePercentageForSafe != 0 https://github.com/code-423n4/2022-02-tribe-turbo/blob/66f27fe51083f49f7935e3fe594ab2380b75dee8/src/modules/TurboClerk.sol#L111
if (customFeePercentageForSafe != 0) return customFeePercentageForSafe;
#0 - Joeysantoro
2022-02-26T21:27:31Z
First safe slot is filled by blank safe in Master construction. Acknowledging other issues
#1 - GalloDaSballo
2022-03-19T16:52:32Z
Agree with sponsor safe0 has a different meaning and it's not supposed to be used.
Rest is not bad.
Because of the first finding, which is duplicate of #29 am bumping this to Medium severity
🌟 Selected for report: gzeon
6776.8683 USDC - $6,776.87
Although Gibber is supposed to behind governance timelock, there are still significant "rug risk" when such privillaged user can remove all fund from a vault unconditionally.
function gib(address to, uint256 assetAmount) external nonReentrant requiresLocalOrMasterAuth { emit SafeGibbed(msg.sender, to, assetAmount); // Withdraw the specified amount of assets from the Turbo Fuse Pool. require(assetTurboCToken.redeemUnderlying(assetAmount) == 0, "REDEEM_FAILED"); // Transfer the assets to the authorized caller. asset.safeTransfer(to, assetAmount); }
Limit gib to certain collateral ratio
#0 - Joeysantoro
2022-02-24T18:48:55Z
This is intended behavior. There will be an extended immutable timelock behind the gibber, so Turbo users will have notice to less and withdraw. The only scenario where they can't is when the boosted strategy is insolvent, which is intended behavior
#1 - GalloDaSballo
2022-03-19T16:24:03Z
While there's something to be appreciated about a simple architecture, I believe that the flexibility of the Fuse Pool would allow to account for insolvency in a trustless way through the Fuse Liquidation code.
Additionally, while the code may be put behind timelock, we can only review the code that is in scope and that we can prove behaves in a certain way.
In this case the warden has identified that the system admin can move funds at any time, without limitation.
Because this type of exploit is contingent on a malicious admin, I believe Medium Severity to be appropriate.
The sponsor intends on using an immutable timelock so for end users of the protocol I highly recommend to verify that statement.
Solidity ^0.8.4 allow the use of custom errors to optimize gas usage. https://blog.soliditylang.org/2021/04/21/custom-errors/
There is no need to subtract https://github.com/code-423n4/2022-02-tribe-turbo/blob/66f27fe51083f49f7935e3fe594ab2380b75dee8/src/TurboMaster.sol#L171
id = safes.length; // Add the safe to the list of Safes. safes.push(safe);
function boost(TurboSafe safe, ERC4626 vault, uint256 feiAmount) public authenticate(address(safe)) {
#0 - GalloDaSballo
2022-03-07T01:39:38Z
I believe the first finding is valid, and would save 3 gas Disagree with the second one, the latest solidity versions won't have extra costs unless you're converting dynamic arrays into memory
3