Platform: Code4rena
Start Date: 06/01/2023
Pot Size: $210,500 USDC
Total HM: 27
Participants: 73
Period: 14 days
Judge: 0xean
Total Solo HM: 18
Id: 203
League: ETH
Rank: 36/73
Findings: 2
Award: $194.03
๐ Selected for report: 0
๐ Solo Findings: 0
๐ Selected for report: CodingNameKiki
Also found by: 0xA5DF, 0xAgro, 0xNazgul, 0xSmartContract, Aymen0909, BRONZEDISC, Bnke0x0, Breeje, Cyfrin, GalloDaSballo, HollaDieWaldfee, IceBear, IllIllI, MyFDsYours, RaymondFam, Ruhum, SaharDevep, Sathish9098, Soosh, Udsen, __141345__, brgltd, btk, carlitox477, chaduke, chrisdior4, cryptonue, delfin454000, descharre, hihen, joestakey, ladboy233, lukris02, luxartvinsec, peanuts, pedr02b2, rotcivegaf, shark, tnevler, yongskiws
121.587 USDC - $121.59
Issue | Instances | |
---|---|---|
L-1 | USE OF FLOATING PRAGMA | 3 |
L-2 | setMinTradeVolume METHOD USES INCORRECT REQUIRE CHECK | 1 |
L-3 | WRONG OPERATOR USED | 1 |
NC-1 | USE REQUIRE INSTEAD OF ASSERT | 20 |
NC-2 | EVENT IS MISSING INDEXED FIELDS | 1 |
NC-3 | SPELLING MISTAKE IN NATSPEC | 2 |
Impact: swcregistry
File: libraries/Fixed.sol 3: pragma solidity ^0.8.9;
File: plugins/aave/ERC20.sol 3: pragma solidity ^0.6.0;
File: plugins/aave/ReentrancyGuard.sol 3: pragma solidity >=0.6.0 <0.8.0;
setMinTradeVolume
METHOD USES INCORRECT REQUIRE CHECKAs MIN_TRADE_VOLUME
is already set by default, the minTradeVolume
assigned by the governance
should be greater than or equal to MIN_TRADE_VOLUME
and not less than or equal to.
File: p1/mixins/Trading.sol 135: function setMinTradeVolume(uint192 val) public governance { 136: require(val <= MIN_TRADE_VOLUME, "invalid minTradeVolume"); 137: emit MinTradeVolumeSet(minTradeVolume, val); 138: minTradeVolume = val; 139: }
In discharge
method of RedemptionBatteryLib
, the function should return if anyone of battery.redemptionRateFloor
or battery.scalingRedemptionRate
equals zero as suggested in Natspec.
So &&
operator should be replaced with ||
operator.
File: p1/mixins/RedemptionBattery.sol 25: // for either: set to 0 to disable 38: if (battery.redemptionRateFloor == 0 && battery.scalingRedemptionRate == 0) return;
Assert should not be used except for tests, require should be used.
Intances (20):
BackingManager.sol
Instance 1BasketHandler.sol
Instance 1StRSR.sol
Instance 1RecollateralizationLib.sol
Instance 1RewardableLib.sol
Instance 1RewardableLib.sol
Instance 2TradeLib.sol
Instance 1TradeLib.sol
Instance 2TradeLib.sol
Instance 3TradeLib.sol
Instance 4Trading.sol
Instance 1StaticATokenLM.sol
Instance 1Asset.sol
Instance 1Asset.sol
Instance 2Asset.sol
Instance 3FiatCollateral.sol
Instance 1RTokenAsset.sol
Instance 1GnosisTrade.sol
Instance 1GnosisTrade.sol
Instance 2GnosisTrade.sol
Instance 3Index event fields make the field more quickly accessible to off-chain tools that parse events. However, note that each index field costs extra gas during emission, so it's not necessarily best to index the maximum allowed per event (three fields). Each event should use three indexed fields if there are three or more fields, and gas usage is not particularly of concern for the events in question. If there are fewer than three fields, all of the fields should be indexed.
Instances (1):
Spelling of Auction should be corrected. Spelling of Maintain should be corrected.
File: contracts/plugins/trading/GnosisTrade.sol 47: // from this trade's acution will all eventually go to origin.
File: p1/BackingManager.sol 89: /// Mointain the overall backing policy; handout assets otherwise
#0 - c4-judge
2023-01-24T22:24:51Z
0xean marked the issue as grade-c
#1 - c4-judge
2023-01-31T16:16:32Z
0xean marked the issue as grade-b
๐ Selected for report: IllIllI
Also found by: 0xA5DF, 0xSmartContract, 0xhacksmithh, AkshaySrivastav, Awesome, Aymen0909, Bauer, Bnke0x0, Breeje, Budaghyan, Cyfrin, Madalad, NoamYakov, RHaO-sec, Rageur, RaymondFam, ReyAdmirado, Rolezn, SAAJ, SaharDevep, Sathish9098, __141345__, amshirif, arialblack14, c3phas, carlitox477, chaduke, delfin454000, descharre, nadin, oyc_109, pavankv, saneryee, shark
72.4433 USDC - $72.44
Issue | Instances | |
---|---|---|
GAS-1 | ++I/I++ SHOULD BE UNCHECKED{++I}/UNCHECKED{I++} WHEN IT IS NOT POSSIBLE FOR THEM TO OVERFLOW | 60 |
GAS-2 | X += Y COSTS MORE GAS THAN X = X + Y FOR STATE VARIABLES | 36 |
GAS-3 | SPLITTING REQUIRE() STATEMENTS THAT USE && SAVES GAS | 32 |
GAS-4 | NO NEED TO EXPLICITLY INITIALIZE VARIABLES WITH DEFAULT VALUES | 2 |
GAS-5 | USE CALLDATA INSTEAD OF MEMORY FOR FUNCTION ARGUMENTS THAT DO NOT GET MUTATED | 7 |
GAS-6 | USE ASSEMBLY TO CHECK FOR ADDRESS(0) | 91 |
GAS-7 | NOT USING THE NAMED RETURN VARIABLES WHEN A FUNCTION RETURNS, WASTES DEPLOYMENT GAS | 8 |
GAS-8 | USAGE OF UINTS/INTS SMALLER THAN 32 BYTES (256 BITS) INCURS OVERHEAD | 21 |
GAS-9 | STATE VARIABLES CAN BE PACKED INTO FEWER STORAGE SLOTS | 1 |
The unchecked keyword is new in solidity version 0.8.0, so this only applies to that version or higher, which these instances are. This saves 30-40 gas per loop.
Instances (60):
Array.sol
Instance 1Array.sol
Instance 2Array.sol
Instance 3Fixed.sol
Instance 1Fixed.sol
Instance 2String.sol
Instance 1AssetRegistry.sol
Instance 1AssetRegistry.sol
Instance 2AssetRegistry.sol
Instance 3AssetRegistry.sol
Instance 4BackingManager.sol
Instance 1BackingManager.sol
Instance 2BasketHandler.sol
Instance 1BasketHandler.sol
Instance 2BasketHandler.sol
Instance 3BasketHandler.sol
Instance 4BasketHandler.sol
Instance 5BasketHandler.sol
Instance 6BasketHandler.sol
Instance 7BasketHandler.sol
Instance 8BasketHandler.sol
Instance 9BasketHandler.sol
Instance 10BasketHandler.sol
Instance 11BasketHandler.sol
Instance 12BasketHandler.sol
Instance 13BasketHandler.sol
Instance 14BasketHandler.sol
Instance 15BasketHandler.sol
Instance 16BasketHandler.sol
Instance 17BasketHandler.sol
Instance 18BasketHandler.sol
Instance 19BasketHandler.sol
Instance 20BasketHandler.sol
Instance 21BasketHandler.sol
Instance 22Distributor.sol
Instance 1Distributor.sol
Instance 2Distributor.sol
Instance 3Distributor.sol
Instance 4RToken.sol
Instance 1RToken.sol
Instance 2RToken.sol
Instance 3RToken.sol
Instance 4RToken.sol
Instance 5RToken.sol
Instance 6RToken.sol
Instance 7RToken.sol
Instance 8RToken.sol
Instance 9RToken.sol
Instance 10RToken.sol
Instance 11RToken.sol
Instance 12RToken.sol
Instance 13StRSR.sol
Instance 1StRSR.sol
Instance 2RecollateralizationLib.sol
Instance 1RecollateralizationLib.sol
Instance 2RecollateralizationLib.sol
Instance 3RewardableLib.sol
Instance 1RewardableLib.sol
Instance 2RewardableLib.sol
Instance 3Trading.sol
Instance 1Instances (36):
Fixed.sol
Instance 1Fixed.sol
Instance 2Fixed.sol
Instance 3Fixed.sol
Instance 4Fixed.sol
Instance 5Fixed.sol
Instance 6Fixed.sol
Instance 7Fixed.sol
Instance 8Auth.sol
Instance 1BasketHandler.sol
Instance 1BasketHandler.sol
Instance 2BasketHandler.sol
Instance 3Distributor.sol
Instance 1Distributor.sol
Instance 2RToken.sol
Instance 1RToken.sol
Instance 2RToken.sol
Instance 3RToken.sol
Instance 4RToken.sol
Instance 5StRSR.sol
Instance 1StRSR.sol
Instance 2StRSR.sol
Instance 3StRSR.sol
Instance 4StRSR.sol
Instance 5StRSR.sol
Instance 6StRSR.sol
Instance 7StRSR.sol
Instance 8StRSR.sol
Instance 9StRSR.sol
Instance 10StRSR.sol
Instance 11StRSR.sol
Instance 12StRSR.sol
Instance 13RecollateralizationLib.sol
Instance 1RecollateralizationLib.sol
Instance 2Saves 3 gas per instance.
Instances (32):
Auth.sol
Instance 1Auth.sol
Instance 2BackingManager.sol
Instance 1BasketHandler.sol
Instance 1Broker.sol
Instance 1Deployer.sol
Instance 1-14Deployer.sol
Instance 15Furnace.sol
Instance 1RevenueTrader.sol
Instance 1RToken.sol
Instance 1RToken.sol
Instance 2RToken.sol
Instance 3RToken.sol
Instance 4RToken.sol
Instance 5StRSR.sol
Instance 1StRSR.sol
Instance 2TradeLib.sol
Instance 1TradeLib.sol
Instance 2Asset.sol
Instance 1If a variable is not set/initialized, it is assumed to have the default value (0 for uint, false for bool, address(0) for addressโฆ). Explicitly initializing it with its default value wastes gas.
Instances (2):
Mark data types as calldata
instead of memory
where possible. This makes it so that the data is not automatically loaded into memory. If the data passed into the function does not need to be changed (like updating values in an array), it can be passed in as calldata
. The one exception to this is if the argument must later be passed into another function that takes an argument that specifies memory
storage.
Instances (7):
Array.sol
Instance 1Array.sol
Instance 2Deployer.sol
Instance 1Deployer.sol
Instance 2Deployer.sol
Instance 3Distributor.sol
Instance 1Distributor.sol
Instance 2Saves 6 gas per instance
Instances (91):
Auth.sol
Instance 1ComponentRegistry.sol
Instance 1ComponentRegistry.sol
Instance 2ComponentRegistry.sol
Instance 3ComponentRegistry.sol
Instance 4ComponentRegistry.sol
Instance 5ComponentRegistry.sol
Instance 6ComponentRegistry.sol
Instance 7ComponentRegistry.sol
Instance 8ComponentRegistry.sol
Instance 9ComponentRegistry.sol
Instance 10AssetRegistry.sol
Instance 1BasketHandler.sol
Instance 1BasketHandler.sol
Instance 2Broker.sol
Instance 1Broker.sol
Instance 2Deployer.sol
Instance 1-14Deployer.sol
Instance 15Distributor.sol
Instance 1Main.sol
Instance 1RevenueTrader.sol
Instance 1RevenueTrader.sol
Instance 2StRSR.sol
Instance 1-2StRSR.sol
Instance 3StRSR.sol
Instance 3StRSR.sol
Instance 4-5StRSR.sol
Instance 4-5StRSR.sol
Instance 6StRSR.sol
Instance 7-8StRSR.sol
Instance 9-10StRSRVotes.sol
Instance 1StRSRVotes.sol
Instance 2Component.sol
Instance 1RecollateralizationLib.sol
Instance 1-2RecollateralizationLib.sol
Instance 3-4Trading.sol
Instance 1Trading.sol
Instance 2ERC20.sol
Instance 1-2ERC20.sol
Instance 3-4ERC20.sol
Instance 5ERC20.sol
Instance 6-7ERC20.sol
Instance 8ERC20.sol
Instance 9-10StaticATokenLM.sol
Instance 1StaticATokenLM.sol
Instance 2StaticATokenLM.sol
Instance 3StaticATokenLM.sol
Instance 4StaticATokenLM.sol
Instance 5StaticATokenLM.sol
Instance 6StaticATokenLM.sol
Instance 7StaticATokenLM.sol
Instance 8StaticATokenLM.sol
Instance 9StaticATokenLM.sol
Instance 10StaticATokenLM.sol
Instance 11StaticATokenLM.sol
Instance 12StaticATokenLM.sol
Instance 13StaticATokenLM.sol
Instance 14StaticATokenLM.sol
Instance 15StaticATokenLM.sol
Instance 16Asset.sol
Instance 1Asset.sol
Instance 2CTokenFiatCollateral.sol
Instance 1CTokenNonFiatCollateral.sol
Instance 1CTokenSelfReferentialCollateral.sol
Instance 1EURFiatCollateral.sol
Instance 1NonFiatCollateral.sol
Instance 1RTokenAsset.sol
Instance 1GnosisTrade.sol
Instance 1GnosisTrade.sol
Instance 2Instances (8):
AssetRegistry.sol
Instance 1RToken.sol
Instance 1RecollateralizationLib.sol
Instance 1TradeLib.sol
Instance 1TradeLib.sol
Instance 2Asset.sol
Instance 1EURFiatCollateral.sol
Instance 1Governance.sol
Instance 1When using elements that are smaller than 32 bytes, your contractโs gas usage may be higher. This is because the EVM operates on 32 bytes at a time. Therefore, if the element is smaller than that, the EVM must use more operations in order to reduce the size of the element from 32 bytes to the desired size.
Instances (21):
File: IDistributor.sol 7: struct RevenueShare { 8: uint16 rTokenDist; // {revShare} A value between [0, 10,000] 9: uint16 rsrDist; // {revShare} A value between [0, 10,000] 10: } 12: /// Assumes no more than 1024 independent distributions. 13: struct RevenueTotals { 14: uint24 rTokenTotal; // {revShare} 15: uint24 rsrTotal; // {revShare} 16: }
File: StRSRP1Votes.sol 22: struct Checkpoint { 23: uint48 fromBlock; 24: uint224 val; 25: }
File: p1/mixins/RecollateralizationLib.sol 24: struct TradingRules { 25: uint192 minTradeVolume; // {UoA} 26: uint192 maxTradeSlippage; // {1} 27: } 29: struct TradeInfo { 30: IAsset sell; 31: IAsset buy; 32: uint192 sellAmount; // {sellTok} 33: uint192 buyAmount; // {buyTok} 34: uint192 sellPrice; // {UoA/sellTok} can be 0 35: uint192 buyPrice; // {UoA/buyTok} 36: } 116: struct BasketRange { 117: uint192 top; // {BU} 118: uint192 bottom; // {BU} 119: } 284: struct MaxSurplusDeficit { 285: CollateralStatus surplusStatus; // starts SOUND 286: uint192 surplus; // {UoA} 287: uint192 deficit; // {UoA} 288: }
File: RToken.sol 67: uint192 public basketsNeeded; // D18{BU} 72: uint192 private allVestAt; // D18{fractional block number} 74: uint192 private lastIssRate; 81: uint192 when; 83: uint192 amtBaskets;
Instances (1):
File: interfaces/IDeployer.sol L19:L48 struct DeploymentParams { // === Revenue sharing === RevenueShare dist; // revenue sharing splits between RToken and RSR // // === Trade sizing === uint192 minTradeVolume; // {UoA} uint192 rTokenMaxTradeVolume; // {UoA} // // === Freezing === uint48 shortFreeze; // {s} how long an initial freeze lasts uint48 longFreeze; // {s} how long each freeze extension lasts // // === Rewards (Furnace + StRSR) === uint192 rewardRatio; // the fraction of available revenues that stRSR holders get each PayPeriod uint48 rewardPeriod; // {s} the atomic unit of rewards, determines # of exponential rounds // // === StRSR === uint48 unstakingDelay; // {s} the "thawing time" of staked RSR before withdrawal // // === BackingManager === uint48 tradingDelay; // {s} how long to wait until starting auctions after switching basket uint48 auctionLength; // {s} the length of an auction uint192 backingBuffer; // {1} how much extra backing collateral to keep uint192 maxTradeSlippage; // {1} max slippage acceptable in a trade // // === RToken === uint192 issuanceRate; // {1/block} number of RToken to issue per block / (RToken value) uint192 scalingRedemptionRate; // {1/hour} max fraction of supply that can be redeemed hourly uint256 redemptionRateFloor; // {qRTok/hour} the lowest possible hourly redemption limit }
#0 - c4-judge
2023-01-24T23:03:29Z
0xean marked the issue as grade-b