Cheesy Pebble Kookaburra
Medium
This issue was reported in a previous audit 2024 here and also in a previous audit 2023 here. However, in the collateral Account
the same issue still exists with assuming 1:1 unwrapping of DSU
into USDC
when reserve.redeem(amount)
is called.
As a consequence, Controller::withdrawWithSignature()
and ControllerIncentivized::withdrawWithSignature()
may not work due to this issue.
In Account::withdraw()
, USDC
may be unwrapped from DSU
to facilitate withdrawal by calling reserve.redeem(amount)
in Account.sol line 103.
However the redeem price may be below 1 in the reserve implementation:
function redeemPrice() public view returns (UFixed18) {
// if overcollateralized, cap at 1:1 redemption / if undercollateralized, redeem pro-rata
return assets().unsafeDiv(dsu.totalSupply()).min(UFixed18Lib.ONE);
}
Account::withdraw()
then calls USDC.push(owner, pushAmount)
with pushAmount
being the amount
. However since unwrapping DSU
to USDC
may not result in 1:1 conversion, this may revert when trying to send more USDC
to the owner than the contract has.
Code snippets:
No response
No response
No response
Controller::withdrawWithSignature()
and ControllerIncentivized::withdrawWithSignature()
may not work due to this issue.
No response
Consider adjusting Account::withdraw()
to transfer the difference between balance before and balance after, similar as in MultiInvoker.sol line 398:
// Account::withdraw()
83 UFixed6 pushAmount = amount.eq(UFixed6Lib.MAX) ? USDC.balanceOf() : USDC.balanceOf().sub(usdcBalance);