Summary
The transferRoyalties function in the Swan contract attempts to transfer tokens from the seller without first checking or requiring approval, leading to failed transactions and potential inconsistent state.
Vulnerability Details
The transferRoyalties function attempts to transfer tokens without verifying approval:
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);
}
This function is called in both list and relist functions:
Impact
Asset listing process fails
No way to determine required approval beforehand
Poor user experience with failed transactions
Tools Used
Manual Review
Recommendations
Add approval check before transfer:
function transferRoyalties(AssetListing storage asset) internal {
uint256 buyerFee = (asset.price * asset.royaltyFee) / 100;
uint256 driaFee = (buyerFee * getCurrentMarketParameters().platformFee) / 100;
uint256 allowance = token.allowance(asset.seller, address(this));
if (allowance < buyerFee) {
revert InsufficientAllowance(allowance, buyerFee);
}
token.transferFrom(asset.seller, address(this), buyerFee);
token.transfer(asset.buyer, buyerFee - driaFee);
token.transfer(owner(), driaFee);
}