Platform: Code4rena
Start Date: 05/01/2023
Pot Size: $90,500 USDC
Total HM: 55
Participants: 103
Period: 14 days
Judge: Picodes
Total Solo HM: 18
Id: 202
League: ETH
Rank: 100/103
Findings: 1
Award: $33.24
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: Lirios
Also found by: 0xcm, 0xsomeone, HE1M, Jeiwan, Koolex, bin2chen, c7e7eff, cergyk, dragotanqueray, evan, ladboy233, synackrst, unforgiven, wallstreetvilkas
33.2422 USDC - $33.24
https://github.com/code-423n4/2023-01-astaria/blob/main/src/ClearingHouse.sol#L114 https://github.com/code-423n4/2023-01-astaria/blob/main/src/ClearingHouse.sol#L169
An attacker can pass malicious tokenContract
and encodedMetaData
values.
The _execute
function is called by safeTransferFrom
and does not perform any input validation on the tokenContract
and encodedMetaData
arguments - neither at the _execute
or safeTransferFrom
levels.
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); } 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); }
Perform input validation on either functions. A comment mentions that the data is useless; if that is the case, then either remove the function altogether or perform input validation regardless - as the function might be adopted further without the proper security mechanisms in place.
#0 - Picodes
2023-01-24T07:56:35Z
You need to develop what could be the impact of this with regards to user funds
#1 - c4-judge
2023-01-24T07:56:45Z
Picodes marked the issue as duplicate of #564
#2 - c4-judge
2023-01-24T07:56:51Z
Picodes marked the issue as partial-25
#3 - c4-judge
2023-02-15T07:33:44Z
Picodes marked the issue as satisfactory
#4 - c4-judge
2023-02-23T21:03:28Z
Picodes changed the severity to QA (Quality Assurance)
#5 - c4-judge
2023-02-24T10:37:08Z
This previously downgraded issue has been upgraded by Picodes
#6 - c4-judge
2023-02-24T10:39:39Z
Picodes marked the issue as not a duplicate
#7 - c4-judge
2023-02-24T10:40:50Z
Picodes marked the issue as duplicate of #521