ClearingHouses are deployed for each new loan and settle payments between Seaport auctions and Astaria Vaults if a liquidation occurs.
However, due to the lack of proper data validation in the current implementation, anyone can fake a token and transfer it to the ClearingHouse to settle the auction, which would undermine the clearing process and harm the entire system.
function safeTransferFrom(
address from, // the from is the offerer
address to,
uint256 identifier,
uint256 amount,
bytes calldata data //empty from seaport
) public {
//data is empty and useless
_execute(from, to, identifier, amount);
}
function _execute(
address tokenContract, // collateral token sending the fake nft
address to, // buyer
uint256 encodedMetaData, //retrieve token address from the encoded data
uint256 // space to encode whatever is needed,
) internal {
IAstariaRouter ASTARIA_ROUTER = IAstariaRouter(_getArgAddress(0)); // get the router from the immutable arg
ClearingHouseStorage storage s = _getStorage();
address paymentToken = bytes32(encodedMetaData).fromLast20Bytes();
uint256 currentOfferPrice = _locateCurrentAmount({
startAmount: s.auctionStack.startAmount,
endAmount: s.auctionStack.endAmount,
startTime: s.auctionStack.startTime,
endTime: s.auctionStack.endTime,
roundUp: true //we are a consideration we round up
});
uint256 payment = ERC20(paymentToken).balanceOf(address(this));
require(payment >= currentOfferPrice, "not enough funds received");
uint256 collateralId = _getArgUint256(21);
// pay liquidator fees here
ILienToken.AuctionStack[] storage stack = s.auctionStack.stack;
uint256 liquidatorPayment = ASTARIA_ROUTER.getLiquidatorFee(payment);
ERC20(paymentToken).safeTransfer(
s.auctionStack.liquidator,
liquidatorPayment
);
ERC20(paymentToken).safeApprove(
address(ASTARIA_ROUTER.TRANSFER_PROXY()),
payment - liquidatorPayment
);
ASTARIA_ROUTER.LIEN_TOKEN().payDebtViaClearingHouse(
paymentToken,
collateralId,
payment - liquidatorPayment,
s.auctionStack.stack
);
if (ERC20(paymentToken).balanceOf(address(this)) > 0) {
ERC20(paymentToken).safeTransfer(
ASTARIA_ROUTER.COLLATERAL_TOKEN().ownerOf(collateralId),
ERC20(paymentToken).balanceOf(address(this))
);
}
ASTARIA_ROUTER.COLLATERAL_TOKEN().settleAuction(collateralId);
}
safeTransferFrom() is a public function without msg.sender access check, encodedMetaData is user data, there no check make sure address paymentToken = bytes32(encodedMetaData).fromLast20Bytes() is the settlementToken.
so the paymentToken can be a fake token worth nothing.
when an attacker call safeTransferFrom before the real auction got settled, the real auction can not settle.
add check make sure paymentToken = settlementToken
The text was updated successfully, but these errors were encountered:
All reactions