Closed sherlock-admin2 closed 8 months ago
2 comment(s) were left on this issue during the judging contest.
ubl4nk commented:
valid ->
vault.setPosition
should be called before _mint (see executeOrder in LeverageModule)
takarez commented:
valid; medium(5)
r0ck3tz
high
The limit orders trade fee can be bypassed through reentrancy
Summary
The leverage position is opened by minting the ERC721 to the trader. The issue lies in the fact that the minting process utilizes the
_safeMint
function, which allows an attacker to execute a reentrancy attack and bypass limit order trade fees.Vulnerability Detail
When the leverage position is opened through the
executeOpen
function of theLeverageModule
contract, the_mint
function is called, utilizing_safeMint
, which could be exploited for a reentrancy attack. Immediately after minting the ERC721 token, the position is updated in the vault. This process allows a potential attacker to receive an ERC721 token before it will get associated with the position in the vault. This vulnerability can be exploited to open a leveraged position with a limit order, setting the trade fee to 0. This is because thetradeFee
is calculated based on the based on valueadditionalSize
of the position, which has not been set yet and is therefore0
. This leads to incorrect calculations, resulting in thetradeFee
being set to 0.Following proof of concept presents attack where attacker opens leveraged position and the limit order with
0
trade fee.Exploit code:
Test case:
Output:
Impact
The severity has been set to high, as it is easy to create a separate service that could enable the opening of leverage positions with limit orders (stop loss and take profit) at a 0 trade fee, allowing the siphoning of value from the Flat Money protocol.
Code Snippet
Tool used
Manual Review
Recommendation
It is recommended to adhere to the checks-effects-interactions pattern by first setting the position in the vault and then triggering the logic within the _mint function. An alternative solution is to use the regular _mint function instead of _safeMint, as the latter is susceptible to reentrancy attacks.
Duplicate of #75