Platform: Code4rena
Start Date: 12/07/2022
Pot Size: $35,000 USDC
Total HM: 13
Participants: 78
Period: 3 days
Judge: 0xean
Total Solo HM: 6
Id: 135
League: ETH
Rank: 47/78
Findings: 2
Award: $70.44
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: joestakey
Also found by: 0x1f8b, 0x52, 0xDjango, 0xNazgul, 0xNineDec, 8olidity, Avci, Bahurum, Bnke0x0, Chom, ElKu, Funen, GimelSec, JC, Junnon, Kaiziron, Meera, PaludoX0, Picodes, ReyAdmirado, Sm4rty, Soosh, Waze, _Adam, __141345__, ak1, aysha, benbaessler, bin2chen, c3phas, cccz, cryptphi, csanuragjain, defsec, exd0tpy, fatherOfBlocks, gogo, hake, hansfriese, itsmeSTYJ, jonatascm, kyteg, mektigboy, oyc_109, pashov, rbserver, rishabh, robee, rokinot, sach1r0, sashik_eth, scaraven, simon135, slywaters
44.2555 USDC - $44.26
ZcToken.sol
1. There is no natspec comment for parameter holder
in withdraw function.
2. There is no natspec comment for parameter holder
in redeem function.VaultTracker.sol
Magic number 1e26
used in 6 functions: addNotional, removeNotional, redeemInterest, transferNotionalFrom, transferNotionalFee and removeNotional.
🌟 Selected for report: joestakey
Also found by: 0x040, 0x1f8b, 0xDjango, 0xNazgul, 0xsam, Avci, Aymen0909, Bnke0x0, CRYP70, ElKu, Fitraldys, Funen, JC, Kaiziron, MadWookie, Meera, ReyAdmirado, Sm4rty, Soosh, TomJ, Waze, _Adam, __141345__, ajtra, benbaessler, c3phas, csanuragjain, durianSausage, exd0tpy, fatherOfBlocks, hake, ignacio, karanctf, kyteg, m_Rassska, oyc_109, rbserver, robee, rokinot, samruna, sashik_eth, simon135, slywaters
26.1808 USDC - $26.18
ZcToken.sol
1. protocol, redeemer and maturity state variables in convertToUnderlying function.
2. protocol, redeemer and maturity state variables in convertToPrincipal function.ZcToken.sol
.convertToUnderlying
and previewRedeem
functions are identical.convertToPrincipal
and previewWithdraw
functions are identical.ZcToken.sol
has the following revert check which repeats twice.
if (block.timestamp < maturity) { revert Maturity(maturity); }
There are 6 functions in VaultTracker.sol ( addNotional, removeNotional, redeemInterest, transferNotionalFrom, transferNotionalFee and removeNotional ) which calculate interest
in the following way:
if (maturityRate > 0) { // calculate marginal interest yield = ((maturityRate * 1e26) / sVault.exchangeRate) - 1e26; } else { yield = ((exchangeRate * 1e26) / sVault.exchangeRate) - 1e26; } uint256 interest = (yield * sVault.notional) / 1e26;
These can be re-written as below:
if (maturityRate > 0) { // calculate marginal interest interest = ((maturityRate * sVault.notional - sVault.notional) / sVault.exchangeRate); } else { interest = ((exchangeRate * sVault.notional - sVault.notional) / sVault.exchangeRate); }
There are two instances of this:
order
. So use it inside the following if-else statements instead of freshly indexing again.#0 - robrobbins
2022-08-31T19:39:53Z
calldata
here is better than memory
it is more in pattern to remove the memory order
and simply use o[i]
throughout. this applies to every function called by these as well as changing the call to them with a memory order
would require changing those signatures as wellthat being said, marking this as resolved because pointing out order
vs o[i]
here is worth recognizing