Platform: Code4rena
Start Date: 24/03/2023
Pot Size: $49,200 USDC
Total HM: 20
Participants: 246
Period: 6 days
Judge: Picodes
Total Solo HM: 1
Id: 226
League: ETH
Rank: 140/246
Findings: 2
Award: $23.92
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: brgltd
Also found by: 0x3b, 0xAgro, 0xGusMcCrae, 0xNorman, 0xRajkumar, 0xSmartContract, 0xTraub, 0xWagmi, 0xWaitress, 0xffchain, 0xhacksmithh, 0xkazim, 0xnev, 3dgeville, ArbitraryExecution, Aymen0909, BRONZEDISC, Bason, Bloqarl, BlueAlder, Brenzee, CodeFoxInc, CodingNameKiki, Cryptor, DadeKuma, DevABDee, Diana, Dug, Englave, Gde, Haipls, HollaDieWaldfee, Ignite, Infect3d, Jerry0x, Josiah, Kaysoft, Koko1912, KrisApostolov, Lavishq, LeoGold, Madalad, PNS, Rappie, RaymondFam, RedTiger, Rickard, Rolezn, Sathish9098, SunSec, T1MOH, UdarTeam, Udsen, Viktor_Cortess, Wander, adriro, ak1, alejandrocovrr, alexzoid, arialblack14, ayden, bin2chen, brevis, btk, c3phas, carlitox477, catellatech, ch0bu, chaduke, ck, climber2002, codeslide, descharre, dingo2077, ernestognw, fatherOfBlocks, favelanky, georgits, helios, hl_, inmarelibero, juancito, ks__xxxxx, lopotras, lukris02, m_Rassska, mahdirostami, maxper, nadin, navinavu, nemveer, p_crypt0, peanuts, pipoca, pixpi, qpzm, rbserver, reassor, roelio, rotcivegaf, scokaf, siddhpurakaran, slvDev, smaul, tnevler, tsvetanovv, turvy_fuzz, vagrant, wen, yac, zzzitron
13.1298 USDC - $13.13
============================================================================================================== # 1 ==============================================================================================================
At line #194 the wrong index
is included in the event.
File: contracts/SafEth/SafEth.sol 182: function addDerivative( 183: address _contractAddress, 184: uint256 _weight 185: ) external onlyOwner { 186: derivatives[derivativeCount] = IDerivative(_contractAddress); 187: weights[derivativeCount] = _weight; 188: derivativeCount++; 189: 190: uint256 localTotalWeight = 0; 191: for (uint256 i = 0; i < derivativeCount; i++) 192: localTotalWeight += weights[i]; 193: totalWeight = localTotalWeight; 194: emit DerivativeAdded(_contractAddress, _weight, derivativeCount); 195: }
For instance, when adding the first derivative
, the third parameter index
to be passed to the DerivativeAdded
event should be 0.
event DerivativeAdded( address indexed contractAddress, uint weight, uint index );
When 188: derivativeCount++;
is called before 194: emit DerivativeAdded(_contractAddress, _weight, derivativeCount);
, the count is incremented and then index
will be 1 instead of 0.
Increment derivativeCount
after emitting event.
emit DerivativeAdded(_contractAddress, _weight, derivativeCount); derivativeCount++;
============================================================================================================== # 2 ==============================================================================================================
Avoid duplicated fragment of code when updating totalWeight
Same logic is repeated here https://github.com/code-423n4/2023-03-asymmetry/blob/main/contracts/SafEth/SafEth.sol#L170 and here https://github.com/code-423n4/2023-03-asymmetry/blob/main/contracts/SafEth/SafEth.sol#L170
Avoid duplicating code for better bugfixing and less prone to errors.
Create a private method _adjustWeight()
called both by adjustWeight()
and addDerivative()
File: contracts/SafEth/SafEth.sol 157: /** 158: @notice - Adds new derivative to the index fund 159: @dev - Weights are only in regards to each other, total weight changes with this function 160: @dev - If you want exact weights either do the math off chain or reset all existing derivates to the weights you want 161: @dev - Weights are approximate as it will slowly change as people stake 162: @param _derivativeIndex - index of the derivative you want to update the weight 163: @param _weight - new weight for this derivative. 164: */ 165: function adjustWeight( 166: uint256 _derivativeIndex, 167: uint256 _weight 168: ) external onlyOwner { 169: _adjustWeight(_derivativeIndex, _weight); 170: emit WeightChange(_derivativeIndex, _weight); 171: } 172: 173: /** 174: @notice - Adds new derivative to the index fund 175: @dev - Weights are only in regards to each other, total weight changes with this function 176: @dev - If you want exact weights either do the math off chain or reset all existing derivates to the weights you want 177: @dev - Weights are approximate as it will slowly change as people stake 178: @param _derivativeIndex - index of the derivative you want to update the weight 179: @param _weight - new weight for this derivative. 180: */ 181: function _adjustWeight( 182: uint256 _derivativeIndex, 183: uint256 _weight 184: ) private onlyOwner { 185: weights[_derivativeIndex] = _weight; 186: uint256 localTotalWeight = 0; 187: for (uint256 i = 0; i < derivativeCount; i++) 188: localTotalWeight += weights[i]; 189: totalWeight = localTotalWeight; 190: } 191: 192: /** 193: @notice - Adds new derivative to the index fund 194: @param _contractAddress - Address of the derivative contract launched by AF 195: @param _weight - new weight for this derivative. 196: */ 197: function addDerivative( 198: address _contractAddress, 199: uint256 _weight 200: ) external onlyOwner { 201: uint256 _derivativeIndex = derivativeCount; 202: 203: derivatives[_derivativeIndex] = IDerivative(_contractAddress); 204: derivativeCount++; 205: _adjustWeight(_derivativeIndex, _weight); 206: 207: emit DerivativeAdded(_contractAddress, _weight, _derivativeIndex); 208: }
#0 - c4-sponsor
2023-04-10T19:05:57Z
toshiSat marked the issue as sponsor confirmed
#1 - c4-judge
2023-04-24T17:50:36Z
Picodes marked the issue as grade-b
🌟 Selected for report: Rolezn
Also found by: 0x3b, 0xGordita, 0xSmartContract, 0xhacksmithh, 0xnev, 0xpanicError, 4lulz, Angry_Mustache_Man, ArbitraryExecution, Aymen0909, Bason, BlueAlder, EvanW, Franfran, HHK, Haipls, IgorZuk, JCN, KrisApostolov, Madalad, MiksuJak, MiniGlome, RaymondFam, ReyAdmirado, Rickard, Sathish9098, Udsen, adriro, alexzoid, anodaram, arialblack14, c3phas, carlitox477, ch0bu, chaduke, codeslide, d3e4, dicethedev, ernestognw, fatherOfBlocks, georgits, hunter_w3b, inmarelibero, lukris02, mahdirostami, maxper, pavankv, pixpi, rotcivegaf, smaul, tank, tnevler, wen, yac
10.7864 USDC - $10.79
Assuming that the number of derivatives will always be lower than 256 (confirmed on Discord by @Toshi), you can save some gas by using uint8
instead of uint256
for derivativeCount
in SafEthStorage.sol
In file contracts/SafEth/SafEthStorage.sol
,
from:
18: uint256 public derivativeCount; // amount of derivatives added to contract
to:
18: uint8 public derivativeCount; // amount of derivatives added to contract
You can find a git patch here, against "main" branch: https://pastebin.com/AiqnbfNZ with password "GqaLNmrB82"
Gas saved is then proportional to the number of derivatives set.
Results by running the tests.
Before: stake (min: 437702, max 660515, avg 527253) unstake (min: 418044, max 571044, avg 516303)
After: stake (min: 436099, max 658912, avg 525650) unstake (min: 416518, max 569256, avg 514514)
#0 - c4-sponsor
2023-04-10T19:06:19Z
toshiSat marked the issue as sponsor acknowledged
#1 - c4-judge
2023-04-23T19:04:10Z
Picodes marked the issue as grade-b