Closed sherlock-admin closed 5 months ago
1 comment(s) were left on this issue during the judging contest.
takarez commented:
valid: high(10)
I think the better solution would be to check if a position exists by either checking the owner of the position (should not be the null address) or the size of the position (should be strictly greater than 0).
Escalate
@rashtrakoff I believe this is possibly misjudged by me as valid based on the PoC provided by a watson mentioned here
Escalate
@rashtrakoff I believe this is possibly misjudged by me as valid based on the PoC provided by a watson mentioned here
You've created a valid escalation!
To remove the escalation from consideration: Delete your comment.
You may delete or edit your escalation comment anytime before the 48-hour escalation window closes. After that, the escalation becomes final.
POC here, was placed in Liquidate.t.sol
function test_cantLiquidatePosition() public {
setWethPrice(1000e8);
uint256 tokenId = announceAndExecuteDepositAndLeverageOpen({
traderAccount: alice,
keeperAccount: keeper,
depositAmount: 100e18,
margin: 10e18,
additionalSize: 30e18,
oraclePrice: 1000e8,
keeperFeeAmount: 0
});
vm.prank(alice);
limitOrderProxy.announceLimitOrder(tokenId, 750e8, 1250e8);
// user announces order
announceAdjustLeverage(alice, tokenId, 3e18, 3e18, 0); //e Alice adds 3e18 margin, 1e18 size
skip(uint256(vaultProxy.minExecutabilityAge())); // must reach minimum executability time
bytes[] memory priceUpdateData = getPriceUpdateData(1000e8);
limitOrderProxy.executeLimitOrder{value: 1}(tokenId, priceUpdateData);
// This reverts, due to [ERC721: invalid token ID]
executeAdjustLeverage(keeper, alice, 1000e8);
}
Escalate This issue is not valid beacause the attack described in the report would not be successful. The attack scenario described in the report would not be successful. There are two situations for an adjustment order:
announcedAdjust.additionalSizeAdjustment
is greater than 0, tx will revert here.announcedAdjust.additionalSizeAdjustment
is equal to 0, it means that the position only has the margin provided by the attacker and does not have additionalSize. This will not lead to bad debts. Moreover, it is self-harm for the attacker.Escalate This issue is not valid beacause the attack described in the report would not be successful. The attack scenario described in the report would not be successful. There are two situations for an adjustment order:
- If
announcedAdjust.additionalSizeAdjustment
is greater than 0, tx will revert here.- If
announcedAdjust.additionalSizeAdjustment
is equal to 0, it means that the position only has the margin provided by the attacker and does not have additionalSize. This will not lead to bad debts. Moreover, it is self-harm for the attacker.
You've created a valid escalation!
To remove the escalation from consideration: Delete your comment.
You may delete or edit your escalation comment anytime before the 48-hour escalation window closes. After that, the escalation becomes final.
Good catch. This issue is invalid. Even if announcedAdjust.additionalSizeAdjustment
= 0 could pass the check, checkLeverageCriteria(newMargin, newAdditionalSize)
would fail. So the path is not possible.
I agree this is invalid.
Planning to accept the escalation and invalidate the issue.
Result: Invalid Has duplicates
Escalations have been resolved successfully!
Escalation status:
@Czar102 why was my escalation rejected?
@securitygrid This is because the first escalation meant the same outcome (even though didn't state it explicitly), and only one escalation can be accepted on an issue not to punish the Lead Judge twice for the same mistake, so I accepted the first one.
@Czar102 Doesn't this affect my escalation ratio?
The protocol team fixed this issue in PR/commit https://github.com/dhedge/flatcoin-v1/pull/295.
LTDingZhen
high
Malicious User can create a position that nobody can liquidate
Summary
In function
executeClose
, after burning an NFT, it will only detect and clear existing limit orders, but not detect existing delayed orders. This allows an attacker to add margin and increase position size to atokenID
where no NFT exists to create a position that cannot be liquidated. The platform risks having bad debt that cannot be eliminated.Vulnerability Detail
In flatcoin protocol, user can close a position by calling
announceLimitOrder
orannounceLeverageClose
. When keepers try to execute the limit order or the delayed order, functionexecuteClose
in LeverageModule is called. InexecuteClose
, there is a check for cancellation of any existing limit orders on the position, but does not cancel an existing Delayed order ifexecuteClose
is called byexecuteLimitOrder()
!When performing leverage adjustments, since the validation of the caller's possession of the NFT is performed at
announceLeverageAdjust
,executeAdjust
does not have a test for the existence of a current position, and allows a position with all parameters 0 to operate normally.Consider path below:
announceLimitOrder
to create a limit order that can be executed immediately.announceLeverageAdjust
to create a delayed order to add some margin and increase position size. Since the limit order has not been executed at this time, all validations inannounceLeverageAdjust
will pass.Impact
Attackers can create positions which nobody can liquidate, so there is a risk that the platform will incur bad debts that cannot be eliminated.
Code Snippet
https://github.com/sherlock-audit/2023-12-flatmoney/blob/main/flatcoin-v1/src/LeverageModule.sol#L255-L317 https://github.com/sherlock-audit/2023-12-flatmoney/blob/main/flatcoin-v1/src/LeverageModule.sol#L147-L248
Tool used
Manual Review
Recommendation
In function executeClose, only cancel any existing limit order on the position is not enough. delayed order should also be canceled.