Open code423n4 opened 2 years ago
Particularly high quality.
Issue | Comments |
---|---|
L1 | Fixed |
L2 | Fixed |
L3 | Fixed |
L4 | Fixed |
L5 | Invalid. ETH constant may be used in several child contract. |
L6 | Admin can monitor it. |
L7 | Invalid. LidoVault can be received ETH from CurveSwap |
L8 | No need to change |
L9 | Fixed |
L10 | Fixed |
N1 | Fixed |
N2 | Fixed |
N3 | Invalid |
N4 | Fixed |
N5 | Fixed |
N6 | Fixed |
N7 | Fixed |
N8 | Fixed |
N9 | No need to change |
N10 | Invalid |
N11 | Invalid |
N12 | Fixed |
N13 | No need to change |
Bumping L1 as a high-severity duplicate of #133. I'm being lenient here as one might argue that the critical step of linking the slippage check of GeneralVault to causing stuck user fund withdrawals was not made. It just happens to be that the LIDO vault was an exception, where users can withdraw directly in stETH, as the warden has reasoned, so I will give the warden the benefit of the doubt this time.
L5 should be addressed IMO. there is an inconsistency between addresses being used. The LIDO vault should be using the ETH constant instead of the null address for ETH, or vice versa. For someone who uses etherscan, he'll see the ETH
constant define and assumes that he should be using that to specify ETH, then wonder why his tx will potentially revert in Metamask.
Low issues: L2, L3, L4, L5, L6, L8, centralisation risk NC issues: L9, L10, N1, N2, N3 (more of sponsor acknowledged), N4, N5, N6, N7 (reasoning is diff from N6), N8, N9, N12, N13 Invalid: L7, N10 (some fields are not worth the extra gas to index), N11 (no justification),
Summary
Low Risk Issues
distributeYield()
to revertapprove()
's return statusETH
constant to child contractIERC20Detailed
receive()
function will lock Ether in contractsafeApprove()
is deprecatedaddress(0x0)
when assigning values toaddress
state variablesTotal: 12 instances over 10 issues
Non-critical Issues
override
function arguments that are unused should have the variable name removed or commented out to avoid compiler warningspublic
functions not called by the contract should be declaredexternal
insteadconstant
s should be defined rather than using magic numbersconst
/immutable
variablesindexed
fieldsTotal: 28 instances over 13 issues
Low Risk Issues
1. Slippage of 1% is too strict
The
GeneralVault
assumes that st tokens are always 1:1 redeemable and therefore the slippage should be negligable. This currently is not the case, specifically for LIDO where the depegging is >4%: https://twitter.com/LidoFinance/status/1525129266689622016 I've marked this as 'Low' rather than 'Medium' because funds can still be withdrawn as LIDO directly, and converted at a later pointThere is 1 instance of this issue:
https://github.com/code-423n4/2022-05-sturdy/blob/78f51a7a74ebe8adfd055bdbaedfddc05632566f/smart-contracts/GeneralVault.sol#L117-L125
2. Mistaken null values cause
distributeYield()
to revertThere are no null checks in the
registerAsset()
function, so admins can mistakenly pass 0x0 to that function, which will cause the for-loop to revert when that asset is reached. I've marked this as 'Low' rather than 'Medium' since the admin can work around it by using the_offset
and_count
input arguments to the function.There is 1 instance of this issue:
https://github.com/code-423n4/2022-05-sturdy/blob/78f51a7a74ebe8adfd055bdbaedfddc05632566f/smart-contracts/YieldManager.sol#L118-L122
3. Can't remove old assets
There is no way to remove old assets added by calls to
registerAsset()
. A disgruntled admin, before their access is revoked, can add a lot of assets and regularly sprinkle them with dust, so the new admins have to submit multiple calls todistributeYield()
with different offsets and counts, to avoid the dust and possible reversion due to running out of gasThere is 1 instance of this issue:
https://github.com/code-423n4/2022-05-sturdy/blob/78f51a7a74ebe8adfd055bdbaedfddc05632566f/smart-contracts/YieldManager.sol#L118-L125
4. Missing checks for
approve()
's return statusSome tokens, such as Tether (USDT) return false rather than reverting if the approval fails. Use OpenZeppelin's
safeApprove()
, which reverts if there's a failure, insteadThere is 1 instance of this issue:
https://github.com/code-423n4/2022-05-sturdy/blob/78f51a7a74ebe8adfd055bdbaedfddc05632566f/smart-contracts/YieldManager.sol#L221
5. Move
ETH
constant to child contractAll of the functions in the
GeneralVault
require0x0
when referring to Ether, not the constant here. Having it here will lead to mistakes down the line. It's only used byCurveswapAdapter
, so it only needs to be there (it currently is also defined there).There is 1 instance of this issue:
https://github.com/code-423n4/2022-05-sturdy/blob/78f51a7a74ebe8adfd055bdbaedfddc05632566f/smart-contracts/GeneralVault.sol#L47
6. Unsafe casts and usage of
IERC20Detailed
The
GeneralVault
is meant to be general, i.e. not specific to Lido or Curve, and therefore should not assume that the asset will always beIERC20Detailed
(not all ERC20 contracts definedecimals()
since it's optional in the spec). UsesafeDecimals()
insteadThere is 1 instance of this issue:
https://github.com/code-423n4/2022-05-sturdy/blob/78f51a7a74ebe8adfd055bdbaedfddc05632566f/smart-contracts/GeneralVault.sol#L122
7. Unused
receive()
function will lock Ether in contractIf the intention is for the Ether to be used, the function should call another function, otherwise it should revert
There is 1 instance of this issue:
https://github.com/code-423n4/2022-05-sturdy/blob/78f51a7a74ebe8adfd055bdbaedfddc05632566f/smart-contracts/LidoVault.sol#L24
8.
safeApprove()
is deprecatedDeprecated in favor of
safeIncreaseAllowance()
andsafeDecreaseAllowance()
. If only setting the initial allowance to the value that means infinite,safeIncreaseAllowance()
can be used insteadThere are 3 instances of this issue:
https://github.com/code-423n4/2022-05-sturdy/blob/78f51a7a74ebe8adfd055bdbaedfddc05632566f/smart-contracts/ConvexCurveLPVault.sol#L141
https://github.com/code-423n4/2022-05-sturdy/blob/78f51a7a74ebe8adfd055bdbaedfddc05632566f/smart-contracts/ConvexCurveLPVault.sol#L146
https://github.com/code-423n4/2022-05-sturdy/blob/78f51a7a74ebe8adfd055bdbaedfddc05632566f/smart-contracts/LidoVault.sol#L102
9. Missing checks for
address(0x0)
when assigning values toaddress
state variablesThere is 1 instance of this issue:
https://github.com/code-423n4/2022-05-sturdy/blob/78f51a7a74ebe8adfd055bdbaedfddc05632566f/smart-contracts/ConvexCurveLPVault.sol#L41
10. Open TODOs
Code architecture, incentives, and error handling/reporting questions/issues should be resolved before deployment
There is 1 instance of this issue:
https://github.com/code-423n4/2022-05-sturdy/blob/78f51a7a74ebe8adfd055bdbaedfddc05632566f/smart-contracts/GeneralVault.sol#L77
Non-critical Issues
1.
override
function arguments that are unused should have the variable name removed or commented out to avoid compiler warningsThere are 2 instances of this issue:
https://github.com/code-423n4/2022-05-sturdy/blob/78f51a7a74ebe8adfd055bdbaedfddc05632566f/smart-contracts/ConvexCurveLPVault.sol#L154
https://github.com/code-423n4/2022-05-sturdy/blob/78f51a7a74ebe8adfd055bdbaedfddc05632566f/smart-contracts/LidoVault.sol#L109
2.
public
functions not called by the contract should be declaredexternal
insteadContracts are allowed to override their parents' functions and change the visibility from
external
topublic
.There are 3 instances of this issue:
https://github.com/code-423n4/2022-05-sturdy/blob/78f51a7a74ebe8adfd055bdbaedfddc05632566f/smart-contracts/CollateralAdapter.sol#L35
https://github.com/code-423n4/2022-05-sturdy/blob/78f51a7a74ebe8adfd055bdbaedfddc05632566f/smart-contracts/GeneralVault.sol#L61
https://github.com/code-423n4/2022-05-sturdy/blob/78f51a7a74ebe8adfd055bdbaedfddc05632566f/smart-contracts/YieldManager.sol#L60
3.
constant
s should be defined rather than using magic numbersThere are 6 instances of this issue:
https://github.com/code-423n4/2022-05-sturdy/blob/78f51a7a74ebe8adfd055bdbaedfddc05632566f/smart-contracts/ConvexCurveLPVault.sol#L40
https://github.com/code-423n4/2022-05-sturdy/blob/78f51a7a74ebe8adfd055bdbaedfddc05632566f/smart-contracts/GeneralVault.sol#L125
https://github.com/code-423n4/2022-05-sturdy/blob/78f51a7a74ebe8adfd055bdbaedfddc05632566f/smart-contracts/LidoVault.sol#L48
4. Redundant cast
The type of the variable is the same as the type to which the variable is being cast
There is 1 instance of this issue:
https://github.com/code-423n4/2022-05-sturdy/blob/78f51a7a74ebe8adfd055bdbaedfddc05632566f/smart-contracts/LidoVault.sol#L140
5. Missing event for critical parameter change
There are 2 instances of this issue:
https://github.com/code-423n4/2022-05-sturdy/blob/78f51a7a74ebe8adfd055bdbaedfddc05632566f/smart-contracts/ConvexCurveLPVault.sol#L37-L49
https://github.com/code-423n4/2022-05-sturdy/blob/78f51a7a74ebe8adfd055bdbaedfddc05632566f/smart-contracts/YieldManager.sol#L64-L67
6. Use a more recent version of solidity
Use a solidity version of at least 0.8.13 to get the ability to use
using for
with a list of free functionsThere are 3 instances of this issue:
https://github.com/code-423n4/2022-05-sturdy/blob/78f51a7a74ebe8adfd055bdbaedfddc05632566f/smart-contracts/GeneralVault.sol#L2
https://github.com/code-423n4/2022-05-sturdy/blob/78f51a7a74ebe8adfd055bdbaedfddc05632566f/smart-contracts/LidoVault.sol#L2
https://github.com/code-423n4/2022-05-sturdy/blob/78f51a7a74ebe8adfd055bdbaedfddc05632566f/smart-contracts/YieldManager.sol#L2
7. Use a more recent version of solidity
Use a solidity version of at least 0.8.4 to get
bytes.concat()
instead ofabi.encodePacked(<bytes>,<bytes>)
Use a solidity version of at least 0.8.12 to getstring.concat()
instead ofabi.encodePacked(<str>,<str>)
There is 1 instance of this issue:
https://github.com/code-423n4/2022-05-sturdy/blob/78f51a7a74ebe8adfd055bdbaedfddc05632566f/smart-contracts/ConvexCurveLPVault.sol#L2
8. Variable names that consist of all capital letters should be reserved for
const
/immutable
variablesIf the variable needs to be different based on which class it comes from, a
view
/pure
function should be used instead (e.g. like this).There is 1 instance of this issue:
https://github.com/code-423n4/2022-05-sturdy/blob/78f51a7a74ebe8adfd055bdbaedfddc05632566f/smart-contracts/LidoVault.sol#L127
9. NatSpec is incomplete
There are 2 instances of this issue:
https://github.com/code-423n4/2022-05-sturdy/blob/78f51a7a74ebe8adfd055bdbaedfddc05632566f/smart-contracts/GeneralVault.sol#L134-L139
https://github.com/code-423n4/2022-05-sturdy/blob/78f51a7a74ebe8adfd055bdbaedfddc05632566f/smart-contracts/YieldManager.sol#L104-L106
10. Event is missing
indexed
fieldsEach
event
should use threeindexed
fields if there are three or more fieldsThere are 4 instances of this issue:
https://github.com/code-423n4/2022-05-sturdy/blob/78f51a7a74ebe8adfd055bdbaedfddc05632566f/smart-contracts/GeneralVault.sol#L24
https://github.com/code-423n4/2022-05-sturdy/blob/78f51a7a74ebe8adfd055bdbaedfddc05632566f/smart-contracts/GeneralVault.sol#L25
https://github.com/code-423n4/2022-05-sturdy/blob/78f51a7a74ebe8adfd055bdbaedfddc05632566f/smart-contracts/GeneralVault.sol#L26
https://github.com/code-423n4/2022-05-sturdy/blob/78f51a7a74ebe8adfd055bdbaedfddc05632566f/smart-contracts/GeneralVault.sol#L27
11. Consider allowing the passing of a referral code
There is 1 instance of this issue:
https://github.com/code-423n4/2022-05-sturdy/blob/78f51a7a74ebe8adfd055bdbaedfddc05632566f/smart-contracts/GeneralVault.sol#L81-L86
12. Remove commented out code
There is 1 instance of this issue:
https://github.com/code-423n4/2022-05-sturdy/blob/78f51a7a74ebe8adfd055bdbaedfddc05632566f/smart-contracts/GeneralVault.sol#L144-L148
13. Consider two-phase ownership transfer
Consider adding a two-phase transfer, where the current owner nominates the next owner, and the next owner has to call
accept*()
to become the new owner. This prevents passing the ownership to an account that is unable to use it.There is 1 instance of this issue:
https://github.com/code-423n4/2022-05-sturdy/blob/78f51a7a74ebe8adfd055bdbaedfddc05632566f/smart-contracts/YieldManager.sol#L26