Minting credit tokens before creditMultiplier
is updated down and redeeming for underlying tokens after creditMultiplier
is updated down would cause an underlying token amount that is a part of pegTokenBalance
to always remain in SimplePSM
contract and be lost
#786
Labels
3 (High Risk)
Assets can be stolen/lost/compromised directly
bug
Something isn't working
primary issue
Highest quality submission among a set of duplicates
sponsor disputed
Sponsor cannot duplicate the issue, or otherwise disagrees this is an issue
sufficient quality report
This report is of sufficient quality
unsatisfactory
does not satisfy C4 submission criteria; not eligible for awards
Lines of code
https://github.com/code-423n4/2023-12-ethereumcreditguild/blob/e3d3e581e0e51a9ecf3a5a0c4e4bd4af32552fc0/src/governance/ProfitManager.sol#L79-L87
https://github.com/code-423n4/2023-12-ethereumcreditguild/blob/e3d3e581e0e51a9ecf3a5a0c4e4bd4af32552fc0/src/loan/SimplePSM.sol#L103-L112
https://github.com/code-423n4/2023-12-ethereumcreditguild/blob/e3d3e581e0e51a9ecf3a5a0c4e4bd4af32552fc0/src/loan/SimplePSM.sol#L87-L93
https://github.com/code-423n4/2023-12-ethereumcreditguild/blob/e3d3e581e0e51a9ecf3a5a0c4e4bd4af32552fc0/src/loan/SimplePSM.sol#L134-L144
Vulnerability details
Impact
As mentioned by the following code comments for
creditMultiplier
,creditMultiplier
can only be updated down.https://github.com/code-423n4/2023-12-ethereumcreditguild/blob/e3d3e581e0e51a9ecf3a5a0c4e4bd4af32552fc0/src/governance/ProfitManager.sol#L79-L87
Before
creditMultiplier
is updated down, a user can call the followingSimplePSM.mint
function to mint some credit tokens by sending some underlying tokens, which are tracked bypegTokenBalance
, to theSimplePSM
contract. When only one user has minted the credit tokens,pegTokenBalance
would equal the sent underlying token amount.https://github.com/code-423n4/2023-12-ethereumcreditguild/blob/e3d3e581e0e51a9ecf3a5a0c4e4bd4af32552fc0/src/loan/SimplePSM.sol#L103-L112
For the same
amountIn
, the value returned by the followingSimplePSM.getRedeemAmountOut
function aftercreditMultiplier
is updated down would be smaller than the value returned by the same function beforecreditMultiplier
is updated down.https://github.com/code-423n4/2023-12-ethereumcreditguild/blob/e3d3e581e0e51a9ecf3a5a0c4e4bd4af32552fc0/src/loan/SimplePSM.sol#L87-L93
Hence, after
creditMultiplier
is updated down, when the same user calls the followingSimplePSM.redeem
function withamountIn
being theamountOut
that was returned by the previousSimplePSM.mint
function call, theamountOut
that equalsgetRedeemAmountOut(amountIn)
would be smaller thanpegTokenBalance
if there still is only one user who has minted credit tokens. In this case,pegTokenBalance -= amountOut
would not reducepegTokenBalance
to 0, andERC20(pegToken).safeTransfer(to, amountOut)
would not transfer all of thepegTokenBalance
underlying tokens out from theSimplePSM
contract.https://github.com/code-423n4/2023-12-ethereumcreditguild/blob/e3d3e581e0e51a9ecf3a5a0c4e4bd4af32552fc0/src/loan/SimplePSM.sol#L134-L144
Since
creditMultiplier
can only be updated down and there are no other functions besides theSimplePSM.redeem
function for transferring the underlying tokens out from theSimplePSM
contract, the underlying token amount that ispegTokenBalance - amountOut
will remain in theSimplePSM
contract forever and hence is lost. When multiple users mint the credit tokens beforecreditMultiplier
is updated down and redeem for the underlying tokens aftercreditMultiplier
is updated down, the same issue also exists in which an underlying token amount that is a part ofpegTokenBalance
would always remain in theSimplePSM
contract and be lost.Proof of Concept
The following steps can occur.
creditMultiplier
is 1e18 at this moment, and Alice calls theSimplePSM.mint
function to mint 100e18 credit tokens by sending 100e18 underlying tokens to theSimplePSM
contract.creditMultiplier
is updated down to 0.7e18.SimplePSM.redeem
function withamountIn
being 100e18 credit tokens to receive 70e18 underlying tokens so 30e18 underlying tokens remain in theSimplePSM
contract.creditMultiplier
can only be updated down and there are no other functions besides theSimplePSM.redeem
function for transferring the underlying tokens out from theSimplePSM
contract, the 30e18 underlying tokens would remain in theSimplePSM
contract forever and be lost.Tools Used
Manual Review
Recommended Mitigation Steps
In the
SimplePSM
contract, an accounting state variable can be added to track the underlying token amount, which is a part ofpegTokenBalance
, that would remain in theSimplePSM
contract due to thecreditMultiplier
reductions; then, a function that is only callable by an authorized role, such ascoreRoles.GOVERNOR
, can also be added for transferring such accounting state variable amount of the underlying token out from theSimplePSM
contract.Assessed type
Timing
The text was updated successfully, but these errors were encountered: