Summary
Buyers can get zero royalty.
Vulnerability Details
In the SwanManager::setMarketParameters
function, the only restriction on the platform fee percentage is that the platform fee cannot exceed 100%
File: contracts/swan/SwanManager.sol#L80-L84
function setMarketParameters(SwanMarketParameters memory _marketParameters) external onlyOwner {
@--> require(_marketParameters.platformFee <= 100, "Platform fee cannot exceed 100%");
_marketParameters.timestamp = block.timestamp;
marketParameters.push(_marketParameters);
}
Which means that platform fee can be 100%. It is 100% of the buyer fee since the platform fee is function of the buyer fee.
File: contracts/swan/Swan.sol#L258-L272
function transferRoyalties(AssetListing storage asset) internal {
@--> uint256 buyerFee = (asset.price * asset.royaltyFee) / 100;
uint256 driaFee = (buyerFee * getCurrentMarketParameters().platformFee) / 100;
token.transferFrom(asset.seller, address(this), buyerFee);
token.transfer(asset.buyer, buyerFee - driaFee);
token.transfer(owner(), driaFee);
}
Impact
In such a case, the buyer can get zero royalties from the seller. Which is completely unfair to the buyer.
Tools Used
Manual review.
Recommendations
et a proper limit for the platformFee percentage. For example, in the SwanManger contract, make the following changes.
File: contracts/swan/SwanManger.sol
contract SwanManager is OwnableUpgradeable {
/*//////////////////////////////////////////////////////////////
STORAGE
//////////////////////////////////////////////////////////////*/
/*** Storage variables ***/
/// @notice The token to be used for fee payments.
ERC20 public token;
++ /// @notice Maximum platform fee percentage.
++ uint256 MAXIMUM_PLATFORM_FEE = 30;
/// @notice Operator addresses that can take actions on behalf of Buyer agents,
/// such as calling `purchase`, or `updateState` for them.
mapping(address operator => bool) public isOperator;
/*** Contract functions ***/
/// @notice Pushes a new market parameters to the marketParameters array.
/// @dev Only callable by owner.
/// @param _marketParameters new market parameters
function setMarketParameters(SwanMarketParameters memory _marketParameters) external onlyOwner {
-- require(_marketParameters.platformFee <= 100, "Platform fee cannot exceed 100%");
++ require(_marketParameters.platformFee <= MAXIMUM_PLATFORM_FEE, "Platform fee cannot exceed the maximum fees");
_marketParameters.timestamp = block.timestamp;
marketParameters.push(_marketParameters);
}
/*** The rest of the contract ***/
}