function buyAndReduceDebt() spend more underlying token than user specified and also code doesn't check that swapFeeBips is less than BIPS_ONE and user can lose some of his underlying token balance that he gave protocol spending approval #301
Labels
2 (Med Risk)
Assets not at direct risk, but function/availability of the protocol could be impacted or leak value
bug
Something isn't working
duplicate-196
satisfactory
satisfies C4 submission criteria; eligible for awards
Lines of code
https://github.com/with-backed/papr/blob/9528f2711ff0c1522076b9f93fba13f88d5bd5e6/src/PaprController.sol#L182-L205
https://github.com/with-backed/papr/blob/9528f2711ff0c1522076b9f93fba13f88d5bd5e6/src/PaprController.sol#L208-L232
https://github.com/with-backed/papr/blob/9528f2711ff0c1522076b9f93fba13f88d5bd5e6/src/PaprController.sol#L493-L517
Vulnerability details
Impact
user can specify fee recipient and fee amount to send to that recipient and it is calculated by
amount * swapFeeBips / BIPS_ONE
but there is no check in the code to make sureswapFeeBips
is less thanBIPS_ONE
and if user set wrong value by mistake or client set malicious values then user would lose his received underlying tokens in the transaction or even he can lose his underlying balance up to spending approval amount of contract from user (in functionbuyAndReduceDebt()
code should transfer fee from user address and it can transfer up to approval amount).Proof of Concept
This is
buyAndReduceDebt()
code:as you can see in line
underlying.transfer(params.swapFeeTo, amountIn * params.swapFeeBips / BIPS_ONE);
code transfers fee (this line has a bug and it should have transferred fee frommsg.sender
) and the amount of the fee is calculated by user specified parameters (which clients can manipulate them) and there is no check for the maximum fee amount and if wrong amounts set for the fee then user can lose a lot of underlying asset (up tounderlying.approval[user][PaprContract]
). functionsincreaseDebtAndSell()
and_increaseDebtAndSell()
don't have checks forswapFeeBips
and if the value was too high user can lose all the underlying balance of he should have received (100% of the amount can go to fee recipient) but in these function user can lose up to the received amount from loan swap. the attack steps is like this:uint256.max
spending approval for underlying token so contract can spend all user underlying balance.buyAndReduceDebt()
.swapFeeBips
very high even higher thanBIPS_ONE
(or buggy client make a mistake and set the value very high wrongly or client do it by intention).swapFeeBips
is bigger thanBIPS_ONE
and user could lose all of his underlying balance.so contract should have protected user by checking the value of the
swapFeeBips
. checkingswapFeeBips < BIPS_ONE
is critical because never ever the should be bigger than the amount user spending and having a max value for fee is reassuring too and can prevent fund loss because of the mistakes or bad clients.There is another bug here which is contract spends more funds of user that what user specified. in the function
increaseDebtAndSell()
and_increaseDebtAndSell()
contract gets fee from amount that is in contract sospending_amount = allowed_amount = fee + user_received_amount
but in the function
buyAndReduceDebt()
contract gets fee from user address sospending_amount = allowed_amount + fee = user_received_amount + fee
, so contract could spend more amount of underlying token than what user specified.This is a important issue because user can lose all of his underlying balance and also contract is always using more funds than user specified in
buyAndReduceDebt()
Tools Used
VIM
Recommended Mitigation Steps
spend what user specified and also check the
swapFee
to make sure user won't lose his funds.The text was updated successfully, but these errors were encountered: