Summary
The function CreateOffer ( )
is supposed to check if both params.points
and params.amount
are greater than zero ( params.points == 0 || params.amount == 0
) , but the current implementation allows the function to proceed if either of these values is non-zero, rather than requiring both to be non-zero
Vulnerability Details
https://github.com/Cyfrin/2024-08-tadle/blob/04fd8634701697184a3f3a5558b41c109866e5f8/src/core/PreMarkets.sol#L45
https://github.com/Cyfrin/2024-08-tadle/blob/04fd8634701697184a3f3a5558b41c109866e5f8/src/core/PreMarkets.sol#L37
Natspec
in the function`s current implementation , states :
* @notice Create offer
* @dev params must be valid, details in CreateOfferParams
@@--> * @dev points and amount must be greater than 0
*/
function createOffer(CreateOfferParams calldata params) external payable {
@@---> * @dev points and amount must be greater than 0
* @dev eachTradeTax must be less than 100%, decimal scaler is 10000
* @dev collateralRate must be more than 100%, decimal scaler is 10000
*/
@audit-issue --> if (params.points == 0 || params.amount == 0) {
revert Errors.AmountIsZero();
}
The operators OR ||
and AND &&
apply the common short-circuiting rules. This means that in the expression params.points || params.amount == 0
, if params.points == 0
evaluates to true, params.amount == 0
will not be evaluated even if it may have side-effects.
However , the function uses the logical OR operator (||
) instead of the logical AND operator (&&
). This means the function will only revert if both params.points
and params.amount
are zero.
Other instance :
In PreMarkets.sol:abortAskOffer ( )#L536 :
* @notice abort ask offer
* @param _stock stock address
* @param _offer offer address
* @notice Only offer owner can abort ask offer
@@--- * @dev Only offer status is virgin or canceled can be aborted
* @dev Market place must be online
*/
function abortAskOffer(address _stock, address _offer) external {
offerInfo.abortOfferStatus
);
if (
offerInfo.offerStatus != OfferStatus.Virgin &&
offerInfo.offerStatus != OfferStatus.Canceled
) {
revert InvalidOfferStatus();
}
}
In DeliveryPlace.sol:SettleAskMaker ( )#L217 :
* @notice Settle ask maker
* @dev caller must be offer authority
@@---> * @dev offer status must be Virgin or Canceled
* @dev market place status must be AskSettling
* @param _offer offer address
* @param _settledPoints settled points
*/
function settleAskMaker(address _offer, uint256 _settledPoints) external {
if (
offerInfo.offerStatus != OfferStatus.Virgin &&
offerInfo.offerStatus != OfferStatus.Canceled
) {
revert InvalidOfferStatus();
}
As you can see there has been several instances where the operator has been wrongly used
Impact
An attacker can exploit this inconsisency to drain user funds
Tools Used
Manual Review
Recommendations
Ensure the correct operator sign are used