Closed code423n4 closed 2 years ago
This is intended because calling deposit on the PCVDeposit is very expensive in terms of gas. Offchain workers will be set up to call the mint function once every 24 hours or once there is a large enough deposit build up.
Downgrading to QA
as the issues does not exist in practice, and the impact is minor.
Lines of code
https://github.com/code-423n4/2022-03-volt/blob/main/contracts/peg/NonCustodialPSM.sol#L259 https://github.com/code-423n4/2022-03-volt/blob/main/contracts/pcv/compound/ERC20CompoundPCVDeposit.sol#L28
Vulnerability details
Impact
The documents specified that
NonCustodialPSM
will directly send collateral into yield venues for system surplus. However, implementation ofNonCustodialPSM.mint
only sends collateral toPCVDeposit
and does not call thepcvDeposit.deposit
function. Collateral within thePCVDeposit
contract will not gain any revenue, and can not be withdrawn until sent into yield venue by an independent call topcvDeposit.deposit
. It is unreasonable to expect users of volt protocol to know this, and if a considerable amount of collateral stays inPCVDeposit
for a long enough time frame, volt might become under-collateralized, thus undermining the entire protocol.Proof of Concept
FEI PCVDeposit
serves as a tunnel to transfer collateral fromNonCustodialPSM
toFuse Pool
. The current implementation can be broken into two partsPCVDeposit
pcvDeposit.deposit
to move collateral withinPCVDeposit
intoFuse Pool
Noticebly, if
pcvDeposit.deposit
is not called, the collateral stays withinPCVDeposit
, and will not be sent into any yield venue for surplus.However, in the
NonCustodialPSM.mint
the function only completes part 1 of a complete deposit (transfer collateral toPCVDeposit
), and does not handle the second partpcvDeposit.deposit
.This creates a risk where the collateral will be held by
PCVDeposit
instead of sent toFuse Pool
if user does not realize callingNonCustodialPSM.mint
is necessary. The collateral then stays inPCVDeposit
until some other happens to callpcvDeposit.deposit
, and does the second transfer in place of original minter.We can't appropriately decide whether this mechanism is by design or accidental, since in the unit test contract of
NonCustodialPSM
, out of the severalmint
called, only one has a pairingdeposit
. Eventually, we judged that the current mechanism will be confusing to end users, and might cause further problems regarding volt value (if yield generated < inflation, volt will not be fully collateralized, and cannot be redeemed when desired).Tools Used
vim, ganache-cli
Recommended Mitigation Steps
Add a call to the
pcvDeposit.deposit
function inNonCustodialPSM.mint
.