Norlend engaged Guardian to perform a follow-up security review of its borrowing lending platform built on top of SparkLend. From the 4th of February to the 7th of February, a team of 6 auditors reviewed the source code in scope.
- Published
- Review window
- February 4 to 7, 2025
- Language
- Solidity
- Chains
- Ethereum
- Sector
- Lending
- 0 Critical
- 0 High
- 3 Medium
- 6 Low
- 0 Informational
Scope
Overview
Norlend engaged Guardian to perform a follow-up security review of its borrowing lending platform built on top of SparkLend. From the 4th of February to the 7th of February, a team of 6 auditors reviewed the source code in scope.
Issues Detected Throughout the engagement only Medium and Low issues were uncovered and promptly remediated by the Norlend team which indicates an overall healthy design and implementation. Following their remediation Guardian believes the protocol to uphold the functionality described for the Lending product.
Findings 9
-
M-01 Medium User Can Pass Arbitrary Fee Amount Logical Error Acknowledged
Description
Function
borrowaccepts an arbitraryfeeAmountthrough aloancall. If Norlend expects a fee to be paid on borrow, a user can just directly interact with the contract and pass afeeAmountof zero to preserve as much capital.Recommendation
Add validation on the expected
feeAmountfor Norlend. Alternatively, consider tieing feeAmount to a fixed percentage of the borrowed/liquidated amount rather than letting the caller supply an arbitrary fee, implement a fixed percentage model (e.g.,feeAmount = (borrowedAmount * feePercentage) /1e18).Resolution
Norlend Team: We own all the wallets our customers utilize, so we are not concerned with external parties calling the contract using their own wallets.
-
M-02 Medium Failed Approvals With USDT Logical Error Resolved
Description
Function
repayapprovesamountand then callsSparkLendto repay the amount. The issue is that thepaybackAmountwithin the BorrowLogic is not necessarily equal toamountpassed, so a portion of the approved amount will be not be utilized.This will lead to DoS with tokens such as USDT which require a 0 approval initially.
Recommendation
For all allowances in Norlend, use
SafeERC20'sforceApprovewhich will force the allowance to go to zero initially to handle tokens such as USDT. Also, use it after an external call to set the approval to zero after the approval is no longer necessary.Resolution
Norlend Team: Added a
forceApprovalfunction to the contract that performs the functionality as needed. We also reset the allowance where needed.Guardian Team: After function
swapis performed, the SwapRouter may still have some token approval leftover if the entireamountInwas not utilized. -
M-03 Medium Lost Borrow Fee Validation Acknowledged
Description
When users borrow via Norlend, a part of the borrowed assets is paid as a fee to the
feeAddress, which is an arbitrary passed parameter, but is validated to be a whitelisted address.However, whitelisted addresses are also the swap routers and the lending pools. This means users may choose to pay the fee to any other whitelisted address resulting in loss of funds for Norlend.
Recommendation
Create a separate validation for the
feeAddress.Resolution
Norlend Team: If an external party wishes to utilize the contract without disrupting its function, they are free to do so.
-
L-01 Low LendingPoolAddress Points To Registry Instead Deployment Resolved
Description
The deployment script currently passes
0x02C3eA4e34C0cBd694D2adFa2c690EECbC1793eE(thePoolAddressesProviderof Spark) to theVanirconstructor, instead of passing0xC13e21B648A5Ee794902342038FF3aDAB66BE987(the SparkLendingPooladdress on Ethereum mainnet).As a result, the Vanir contract is initialized with the wrong contract reference thereby preventing it from interacting correctly with the Spark lending protocol.
If the contract is meant to integrate with Spark Lend on mainnet, the
LendingPooladdress (0xC13e21B648A5Ee794902342038FF3aDAB66BE987) should replace thePoolAddressesProvideraddress in the script.Using the
PoolAddressesProviderdirectly is incorrect in this context because Norlend specifically needs the activeLendingPoolto perform supply/borrow/repay operations, not just an address provider.Recommendation
Update the constructor call in
DeployVanir(or any relevant deployment script) to use0xC13e21B648A5Ee794902342038FF3aDAB66BE987instead of0x02C3eA4e34C0cBd694D2adFa2c690EECbC1793eE.Resolution
Norlend Team: Resolved.
-
L-02 Low No Controls On Liquidation Fee Amount Validation Resolved
Description
During liquidation, the user pays an additional
feeAmountfrom their collateral. ThisfeeAmountis arbitrarily set by the admin within theirLiquidationRequest, and can vary each time.Without fee validation, the fee may be too small or too large, negatively impacting the protocol and user respectively.
Recommendation
Consider adding on-chain validations for
feeAmounton liquidations, or clearly document the fee calculation behavior of your backend system.Resolution
Norlend Team: We have a breakdown of the calculations documented in our backend.
-
L-03 Low Failed Liquidations With Low Target LTV Warning Resolved
Description
Norlend has a target LTV for liquidation within its backend system. If the LTV which Norlend is targetting has a large delta between the current LTV, all liquidation calls will fail as more amountIn is necessary than is approved and available for swap.
Recommendation
Clearly document this behavior and appropriately set the target LTV.
Resolution
Norlend Team: This is dependent on providing the correct parameters, we have found a target range that works for us and can adjust it to lesser deltas if needed.
-
L-04 Low Failing Tests Warning Acknowledged
Description
The tests are meant to simulate Norlend's operations with current backend configurations, however numerous tests are failing. Some reasons for failure include but are not limited to: 1. Lack of pinned fork block number 2. Improper Target LTV's for partial liquidations 3. Incorrect
feeAmountcalculation within the testsAll tests should be passing prior to deployment.
Recommendation
Fix all tests and align them with Norlend's backend systems.
Resolution
Norlend Team: Acknowledged.
-
L-05 Low No Events Emitted On Funds Rescue Event Acknowledged
Description
Two new functions has been added to the contract to enable the admin to reduce funds - ‘
transfer’ and ‘transferEth’. There are no events emitted to notify for the action happening.Recommendation
Consider if you should emit events in these two functions.
Resolution
Norlend Team: We have no needs for these events, we utilize a blockchain listener that tracks all Norlend-related activity.
-
L-06 Low Frozen Pool Will Lead To Fail Liquidations Warning Acknowledged
Description
When the reserve configuration in
SparkLend isFrozen, supplying liquidity is prevented by repays and withdraws are permitted. If the configuration were set to frozen, most Norlend liquidations would fail since functionswap()attempts to supply liquidity that wasn't used as part of the swap cost.Recommendation
Clearly document this risk.
Resolution
Norlend Team: Acknowledged.
No findings match.
Put your code through the same review.
This review started with a conversation about scope. Tell us what you are building and we will plan yours with you.