Open hats-bug-reporter[bot] opened 3 months ago
In such case, User can directly call sellFor()
which has _receiver
param.
function sellFor(address _receiver, uint _depositAmount, uint _minAmountOut)
Issuance tokens will be burned from sellFor()
function caller:
221 // Burn issued token from user
222 _burn(_msgSender(), _depositAmount);
and the passed receiver
in sellFor()
can get the collateral/USDC/USDT.
259 // Transfer tokens to receiver
260 collateralToken.transfer(_receiver, collateralRedeemAmount);
Correct me, if i am missing something
Correct, but it deems the regular sell
function useless, thus the severity.
Its actually not usless. sell()
is for self transferand
sellFor()` is desired destination address transfer. Its intended functionality for users.
I just showcase how said functionality doesn't work in an edge-case scenario.
I would say invalid, as sellFor() allows for targeted address
@FHieser @0xRizwan thanks, yes its invalid
Github username: @PlamenTSV Twitter username: @p_tsanev Submission hash (on-chain): 0x314a2162070e25d8efeb5fdde4a581788be97df0b376b2e703b8b59c760e615f Severity: low
Description: Description\ The
RedeemingBondingCurveBase_v1.sol
is a part of the Funding Manager Module and involves locking up collateral for minting issuance tokens. It allows to buy/sell for the user himself and buyFor/sellFor to buy on behalf of someone else. However, block-list ERC20's could make collateral unredeemable for certain users, due to the hardcodedmsg.sender
address.Attack Scenario\ This occurs inside
_sellOrder
andsellFor
._sellOrder
takes as parameters a receiver who will be the address whose balance is lowered and collateral transfered to. Due to the functionsellFor
passing themsg.sender
as the receiver, instead of letting the user provide a destination address, the collateral can remain stuck if themsg.sender
is blocked by these tokens (USDC, USDT most notably)Attachments
Proof of Concept (PoC) File
Revised Code File (Optional)
function _sellOrder(
address holder address _receiver, uint _depositAmount, uint _minAmountOut ) internal returns (uint totalCollateralTokenMovedOut, uint issuanceFeeAmount) { _validateDepositAmount(_depositAmount); // Get protocol fee percentages and treasury addresses ( address collateralTreasury, address issuanceTreasury, uint collateralSellFeePercentage, uint issuanceSellFeePercentage ) = _getFunctionFeesAndTreasuryAddresses( bytes4(keccak256(bytes("_sellOrder(address, uint, uint)"))) );
_burn(holder, _depositAmount);
}
The mitigation is as simple as letting users provide a different destination of their choosing. Then set the tokens to be burned from the hardcoded
msg.sender
, but the collateral to be sent to the given destination. In our case we add a holder=msg.sender and keep the receiver as a standalone variable.