Platform: Code4rena
Start Date: 04/03/2024
Pot Size: $88,500 USDC
Total HM: 31
Participants: 105
Period: 11 days
Judge: ronnyx2017
Total Solo HM: 7
Id: 342
League: ETH
Rank: 18/105
Findings: 3
Award: $742.93
π Selected for report: 0
π Solo Findings: 0
π Selected for report: 0xjuan
Also found by: CaeraDenoir, Tigerfrake, Timenov, novamanbg, santiellena
398.0218 USDC - $398.02
Malicious users can change other user's position by calling execute
in V3Utils.sol
and earn tokens - High severity
Consider the following scenario:
The execute
function in V3Utils.sol
does not have any access control so any approved tokens to the V3Utils contract are put in danger.
Manual Review
Access control should be added to the execute
function in V3Utils.
ERC721
#0 - c4-pre-sort
2024-03-22T16:35:48Z
0xEVom marked the issue as duplicate of #141
#1 - c4-pre-sort
2024-03-22T16:35:51Z
0xEVom marked the issue as sufficient quality report
#2 - c4-judge
2024-03-31T16:00:04Z
jhsagd76 marked the issue as satisfactory
π Selected for report: 0xjuan
Also found by: 0rpse, 0x175, 0xAlix2, 0xBugSlayer, 0xloscar01, Ali-_-Y, Arz, CaeraDenoir, JohnSmith, Ocean_Sky, SpicyMeatball, alix40, ayden, falconhoof, givn, iamandreiski, kinda_very_good, nmirchev8, nnez, novamanbg, stackachu, wangxx2026
17.3162 USDC - $17.32
In V3Vault.sol
user can create a position that cannot be liquidated, simply by implementing a onERC721Received function of the NFT owner contract, causing safeTransferFrom to revert - High severity.
The liquidate function in V3Vault.sol
makes an internal call to _cleanUpLoan.
https://github.com/code-423n4/2024-03-revert-lend/blob/457230945a49878eefdc1001796b10638c1e7584/src/V3Vault.sol#L744
_cleanUpLoan
uses safeTransferFrom()
to transfer the NFT back to the owner.
https://github.com/code-423n4/2024-03-revert-lend/blob/457230945a49878eefdc1001796b10638c1e7584/src/V3Vault.sol#L1083
safeTransferFrom
will always revert if the onERC721Received
owner function does not return the acceptance magic value to accept the transfer.
https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/utils/ERC721Utils.sol?source=post_page-----8a1fb636fcd1--------------------------------#L22-L47
As a result a user could create a onERC721Received
that does not return the acceptance magic value causing the whole liquidate function to revert.
There are two cases in which the safeTransferFrom will revert:
onERC721Received
IERC721Receiver.onERC721Received.selector
in all casesManual Review
The solution would be to use transferFrom() which will never revert.
ERC721
#0 - c4-pre-sort
2024-03-18T18:41:19Z
0xEVom marked the issue as sufficient quality report
#1 - c4-pre-sort
2024-03-18T18:41:57Z
0xEVom marked the issue as duplicate of #54
#2 - c4-judge
2024-03-31T13:02:23Z
jhsagd76 marked the issue as satisfactory
π Selected for report: falconhoof
327.5899 USDC - $327.59
https://github.com/code-423n4/2024-03-revert-lend/blob/435b054f9ad2404173f36f0f74a5096c894b12b7/src/automators/AutoExit.sol#L200 https://github.com/code-423n4/2024-03-revert-lend/blob/435b054f9ad2404173f36f0f74a5096c894b12b7/src/automators/Automator.sol#L221
Malicious actor can launch a gas griefing attack on a operator executing execute
in AutoExit.sol
. Since griefing attacks have no economic incentive for the attacker and it also requires operators it should be Medium severity.
The execute function is meant to be called by a "revert controlled bot (operator)".
However the execute
function in AutoExit.sol
calls _transferToken
which will perform the following unsafe external call if the token being passed is WETH:
(bool sent,) = to.call{value: amount}("");
Now (bool sent, )
is actually the same as writing (bool sent, bytes memory data)
which basically means that even though the data is omitted it doesnβt mean that the contract does not handle it. Actually, the way it works is the bytes data that was returned from the "to" address will be copied to memory. Memory allocation becomes very costly if the payload is big, so this means that if a "to address" implements a fallback function that returns a huge payload, then the msg.sender of the transaction, in our case the "revert controlled bot (operator)", will have to pay a huge amount of gas for copying this payload to memory.
Manual Review
Use a low-level assembly call since it does not automatically copy return data to memory
bool success; assembly { success := call(gasLimit, to, amount, 0, 0, 0, 0) }
ETH-Transfer
#0 - c4-pre-sort
2024-03-20T14:09:00Z
0xEVom marked the issue as duplicate of #459
#1 - c4-pre-sort
2024-03-20T14:09:04Z
0xEVom marked the issue as sufficient quality report
#2 - c4-judge
2024-03-31T15:58:40Z
jhsagd76 marked the issue as satisfactory