Platform: Code4rena
Start Date: 14/04/2022
Pot Size: $75,000 USDC
Total HM: 8
Participants: 72
Period: 7 days
Judge: Jack the Pug
Total Solo HM: 2
Id: 110
League: ETH
Rank: 65/72
Findings: 1
Award: $54.33
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: Dravee
Also found by: 0v3rf10w, 0x1f8b, 0xAsm0d3us, 0xBug, 0xDjango, 0xNazgul, 0xkatana, CertoraInc, Cityscape, Funen, Hawkeye, IllIllI, MaratCerby, SolidityScan, TerrierLover, TomFrenchBlockchain, Tomio, TrungOre, bae11, berndartmueller, csanuragjain, defsec, delfin454000, ellahi, fatherOfBlocks, gs8nrv, gzeon, horsefacts, ilan, jah, joestakey, joshie, kebabsec, kenta, nahnah, oyc_109, rayn, rfa, robee, saian, securerodd, simon135, slywaters, sorrynotsorry, tchkvsky, teryanarmen, z3s
54.333 USDC - $54.33
diff --git a/src/StakedCitadelVester.sol b/src/StakedCitadelVester.sol index a76b496..c8279e5 100644 --- a/src/StakedCitadelVester.sol +++ b/src/StakedCitadelVester.sol @@ -21,10 +21,10 @@ contract StakedCitadelVester is keccak256("CONTRACT_GOVERNANCE_ROLE"); struct VestingParams { - uint256 unlockBegin; - uint256 unlockEnd; uint256 lockedAmounts; uint256 claimedAmounts; + uint128 unlockBegin; + uint128 unlockEnd; } IERC20Upgradeable public vestingToken; @@ -140,8 +140,8 @@ contract StakedCitadelVester is vesting[recipient].lockedAmounts = vesting[recipient].lockedAmounts + _amount; - vesting[recipient].unlockBegin = _unlockBegin; - vesting[recipient].unlockEnd = _unlockBegin + vestingDuration; + vesting[recipient].unlockBegin = uint128(_unlockBegin); + vesting[recipient].unlockEnd = uint128(_unlockBegin + vestingDuration); emit Vest( recipient,
saleStart
SLOADdiff --git a/.gas-snapshot b/.gas-snapshot index 48730dc..d6e94a8 100644 --- a/.gas-snapshot +++ b/.gas-snapshot @@ -11,7 +11,7 @@ MintAndDistributeTest:testMintAndDistribute() (gas: 4491731) MintingTest:testExampleEpochRates() (gas: 34165) MintingTest:testSetCitadelDistributionSplit() (gas: 153248) MintingTest:testSetFundingPoolWeight() (gas: 245002) -KnightingRoundTest:testKnightingRoundIntegration() (gas: 3787844) +KnightingRoundTest:testKnightingRoundIntegration() (gas: 3787749) SupplyScheduleTest:testExampleEpochRates() (gas: 34187) SupplyScheduleTest:testSetEpochRate() (gas: 102979) SupplyScheduleTest:testSetMintingStart() (gas: 105371) diff --git a/src/KnightingRound.sol b/src/KnightingRound.sol index 2679c22..b9403db 100644 --- a/src/KnightingRound.sol +++ b/src/KnightingRound.sol @@ -164,9 +164,11 @@ contract KnightingRound is GlobalAccessControlManaged, ReentrancyGuardUpgradeabl uint8 _daoId, bytes32[] calldata _proof ) external gacPausable returns (uint256 tokenOutAmount_) { - require(saleStart <= block.timestamp, "KnightingRound: not started"); + uint256 _saleStart = saleStart; + + require(_saleStart <= block.timestamp, "KnightingRound: not started"); require( - block.timestamp < saleStart + saleDuration, + block.timestamp < _saleStart + saleDuration, "KnightingRound: already ended" ); require(_tokenInAmount > 0, "_tokenInAmount should be > 0");
diff --git a/.gas-snapshot b/.gas-snapshot index d6e94a8..a1f7842 100644 --- a/.gas-snapshot +++ b/.gas-snapshot @@ -7,7 +7,7 @@ FundingTest:testFailClaimAssetToTreasury() (gas: 51815) FundingTest:testSetAssetCap() (gas: 510714) FundingTest:testSweep() (gas: 54023) SetupAndKnightingRoundTest:testFundingOraclesFlow() (gas: 166) -MintAndDistributeTest:testMintAndDistribute() (gas: 4491731) +MintAndDistributeTest:testMintAndDistribute() (gas: 4491609) MintingTest:testExampleEpochRates() (gas: 34165) MintingTest:testSetCitadelDistributionSplit() (gas: 153248) MintingTest:testSetFundingPoolWeight() (gas: 245002) diff --git a/src/CitadelMinter.sol b/src/CitadelMinter.sol index c4ed18f..78dbc2f 100644 --- a/src/CitadelMinter.sol +++ b/src/CitadelMinter.sol @@ -341,7 +341,7 @@ contract CitadelMinter is uint256 cachedTotalFundingPoolWeight = totalFundingPoolWeight; require(length > 0, "CitadelMinter: no funding pools"); - for (uint256 i; i < length; ++i) { + for (uint256 i; i < length; /** See below ++i */) { address pool = fundingPools.at(i); uint256 weight = fundingPoolWeights[pool]; @@ -356,6 +356,7 @@ contract CitadelMinter is pool, amount ); + unchecked { ++i; } } }
diff --git a/.gas-snapshot b/.gas-snapshot index 9e8c399..a67d5c5 100644 --- a/.gas-snapshot +++ b/.gas-snapshot @@ -7,7 +7,7 @@ FundingTest:testFailClaimAssetToTreasury() (gas: 51815) FundingTest:testSetAssetCap() (gas: 510714) FundingTest:testSweep() (gas: 54023) SetupAndKnightingRoundTest:testFundingOraclesFlow() (gas: 166) -GasTest:testGas_Vest() (gas: 61826) +GasTest:testGas_Vest() (gas: 61678) MintAndDistributeTest:testMintAndDistribute() (gas: 4491609) MintingTest:testExampleEpochRates() (gas: 34165) MintingTest:testSetCitadelDistributionSplit() (gas: 153248) diff --git a/src/StakedCitadelVester.sol b/src/StakedCitadelVester.sol index c8279e5..ce0375e 100644 --- a/src/StakedCitadelVester.sol +++ b/src/StakedCitadelVester.sol @@ -106,15 +106,17 @@ contract StakedCitadelVester is * @return The number of tokens currently claimable. */ function claimableBalance(address recipient) public view returns (uint256) { - uint256 locked = vesting[recipient].lockedAmounts; - uint256 claimed = vesting[recipient].claimedAmounts; - if (block.timestamp >= vesting[recipient].unlockEnd) { + VestingParams storage vestingRecipient = vesting[recipient]; + + uint256 locked = vestingRecipient.lockedAmounts; + uint256 claimed = vestingRecipient.claimedAmounts; + if (block.timestamp >= vestingRecipient.unlockEnd) { return locked - claimed; } return - ((locked * (block.timestamp - vesting[recipient].unlockBegin)) / - (vesting[recipient].unlockEnd - - vesting[recipient].unlockBegin)) - claimed; + ((locked * (block.timestamp - vestingRecipient.unlockBegin)) / + (vestingRecipient.unlockEnd - + vestingRecipient.unlockBegin)) - claimed; } /// ========================= @@ -136,18 +138,20 @@ contract StakedCitadelVester is ) external { require(msg.sender == vault, "StakedCitadelVester: only xCTDL vault"); require(_amount > 0, "StakedCitadelVester: cannot vest 0"); + + VestingParams storage vestingRecipient = vesting[recipient]; - vesting[recipient].lockedAmounts = - vesting[recipient].lockedAmounts + + vestingRecipient.lockedAmounts = + vestingRecipient.lockedAmounts + _amount; - vesting[recipient].unlockBegin = uint128(_unlockBegin); - vesting[recipient].unlockEnd = uint128(_unlockBegin + vestingDuration); + vestingRecipient.unlockBegin = uint128(_unlockBegin); + vestingRecipient.unlockEnd = uint128(_unlockBegin + vestingDuration); emit Vest( recipient, - vesting[recipient].lockedAmounts, + vestingRecipient.lockedAmounts, _unlockBegin, - vesting[recipient].unlockEnd + vestingRecipient.unlockEnd ); }