Platform: Code4rena
Start Date: 01/08/2023
Pot Size: $91,500 USDC
Total HM: 14
Participants: 80
Period: 6 days
Judge: gzeon
Total Solo HM: 6
Id: 269
League: ETH
Rank: 40/80
Findings: 2
Award: $174.13
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: Team_FliBit
Also found by: 0x70C9, 3docSec, 8olidity, DavidGiladi, Krace, LokiThe5th, Rolezn, Sathish9098, UniversalCrypto, banpaleo5, catellatech, digitizeworx, fatherOfBlocks, hpsb, j4ld1na, josephdara, kutugu, niser93, nonseodion, oakcobalt, osmanozdemir1, pep7siup, ravikiranweb3, said, sivanesh_808
15.3494 USDC - $15.35
https://github.com/code-423n4/2023-08-goodentry/blob/71c0c0eca8af957202ccdbf5ce2f2a514ffe2e24/contracts/RangeManager.sol#L196 https://github.com/code-423n4/2023-08-goodentry/blob/71c0c0eca8af957202ccdbf5ce2f2a514ffe2e24/contracts/RangeManager.sol#L201 https://github.com/code-423n4/2023-08-goodentry/blob/71c0c0eca8af957202ccdbf5ce2f2a514ffe2e24/contracts/RangeManager.sol#L190-L202
Users who have not granted allowance for the contract to spend their tokens might encounter failed deposits, disrupting the expected flow of interactions. Inconsistent behavior and a lack of clarity in token deposits could lead to user confusion and reduced trust in the contract's functionality.
The lines where tokens are deposited into the lending pool without checking the contract's allowance to spend those tokens.
if (asset0_amt > 0) { ASSET_0.safeIncreaseAllowance(address(LENDING_POOL), asset0_amt); LENDING_POOL.deposit(address(ASSET_0), asset0_amt, msg.sender, 0); } if (asset1_amt > 0) { ASSET_1.safeIncreaseAllowance(address(LENDING_POOL), asset1_amt); LENDING_POOL.deposit(address(ASSET_1), asset1_amt, msg.sender, 0); }
In the cleanup function, you are depositing tokens directly into the lending pool without checking the allowance of the contract to spend those tokens. This might result in the contract being unable to deposit tokens on behalf of the user if the allowance is not set correctly.
This is where tokens are deposited directly into the lending pool without checking the allowance. Line196
LENDING_POOL.deposit(address(ASSET_0), asset0_amt, msg.sender, 0);
and
LENDING_POOL.deposit(address(ASSET_1), asset1_amt, msg.sender, 0);
In these lines, the contract is depositing asset0_amt
and asset1_amt
tokens directly into the lending pool on behalf of the user (msg.sender
) without explicitly checking if the contract has been allowed by the user to spend those tokens. This can lead to a situation where the contract is unable to deposit tokens on behalf of the user if the allowance is not set correctly, potentially causing unexpected behavior and usability issues.
Imagine two users, Alice and Bob, interacting with the smart contract that contains the cleanup
function. Alice has approved the contract to spend 100 tokens of ASSET_0
, while Bob has not approved any allowance for the contract.
Initial State:
ASSET_0
tokens: 100 tokensASSET_0
tokens: 200 tokensASSET_0
tokens: 100 tokensASSET_0
tokens: 0 tokensInteraction 1: Alice Calls removeAssetsFromStep
Function
removeAssetsFromStep
function, triggering the cleanup
function.cleanup
function attempts to deposit Alice's ASSET_0
tokens (100 tokens) into the lending pool.Interaction 2: Bob Calls removeAssetsFromStep
Function
removeAssetsFromStep
function, triggering the cleanup
function.cleanup
function attempts to deposit Bob's ASSET_0
tokens (200 tokens) into the lending pool.Result:
In this scenario, the issue becomes apparent when Bob interacts with the contract. The cleanup
function blindly attempts to deposit tokens into the lending pool without checking the allowance for each user. This results in a discrepancy in behavior between users who have granted allowance and those who have not. As a result, Bob's tokens cannot be deposited, potentially leading to confusion and inconsistent behavior for users.
VsCode
The contract should first check the allowance of the tokens before attempting to deposit them into the lending pool. If the allowance is insufficient, the contract should guide the user to set the necessary allowance or provide instructions on how to proceed.
Access Control
#0 - c4-pre-sort
2023-08-09T14:59:00Z
141345 marked the issue as duplicate of #287
#1 - c4-judge
2023-08-20T15:08:59Z
gzeon-c4 marked the issue as duplicate of #137
#2 - c4-judge
2023-08-20T15:09:19Z
gzeon-c4 changed the severity to QA (Quality Assurance)
#3 - c4-judge
2023-08-20T17:42:56Z
gzeon-c4 marked the issue as grade-b
🌟 Selected for report: catellatech
Also found by: 0xSmartContract, K42, Sathish9098, digitizeworx
GoodEntry is a perpetual options trading platform that is built on top of Uniswap v3. It uses single-tick liquidity to provide users with limited downside exposure. The protocol consists of three main components:
TRs are ERC-20 tokens that represent single-tick liquidity on Uniswap v3. They can be used to trade perps with limited downside. ezVaults are smart contracts that hold TRs and rebalance the underlying liquidity as needed. The lending pool is a forked version of Aave v2 that allows users to borrow and lend TRs.
The core idea behind GoodEntry is that single-tick liquidity in Uniswap behaves as a limit order, whose payout is similar to writing an option. Borrowing such liquidity and removing it from the tick gives a payout similar to buying an option.
The protocol has been audited by several security firms and is now under audit on the platform of Code4rena and it has a high level of code coverage. However, there are still some potential risks that should be considered before using the protocol.
The lending pool is a centralized component of the protocol. This means that if the lending pool is hacked, it could lead to the loss of user funds. Additionally, the lending pool is controlled by a single entity, which could lead to censorship or other problems.
The mechanism of the protocol is complex and there are some potential risks that should be considered. For example, if the price of the underlying asset moves significantly, it could lead to liquidation of user positions. Additionally, the protocol is not fully collateralized, which means that there is a risk of default.
The protocol is designed to be a decentralized platform, but there are some potential systemic risks that should be considered. For example, if a large number of users were to sell their TRs at the same time, it could lead to a crash in the price of the protocol's tokens. Additionally, the protocol is dependent on the underlying liquidity of Uniswap v3, which could pose a risk if the liquidity of Uniswap v3 were to decrease.
GoodEntry is a promising project with a lot of potential.
GoodEntry is a promising project with a lot of potential. However, there are some risks that should be considered before using the protocol. The protocol should be decentralized, fully collateralized, and stress-tested to mitigate the potential risks.
31 hours
#0 - c4-judge
2023-08-20T17:08:13Z
gzeon-c4 marked the issue as grade-b