The StakedCitadel contract's balance() function is supposed to return the balance of the vault + the balance of the strategy. But, it only returns the balance of the vault. The balance is used to determine the number of shares that should be minted when depositing funds into the vault and the number of shares that should be burned when withdrawing funds from it.
Since most of the funds will be located in the strategy, the vault's balance will be very low. Some of the issues that arise from this:
You can't deposit to a vault that already minted shares but has no balance of the underlying token:
Now, the vault received 15 tokens. 10 from Alice and 5 from Bob. But Alice only has 10 shares while Bob has 50. Thus, Bob can withdraw more tokens than he should be able to.
It simply breaks the whole accounting of the vault.
Lines of code
https://github.com/code-423n4/2022-04-badger-citadel/blob/main/src/StakedCitadel.sol#L291-L295 https://github.com/code-423n4/2022-04-badger-citadel/blob/main/src/StakedCitadel.sol#L772-L776 https://github.com/code-423n4/2022-04-badger-citadel/blob/main/src/StakedCitadel.sol#L881-L893
Vulnerability details
Impact
The StakedCitadel contract's
balance()
function is supposed to return the balance of the vault + the balance of the strategy. But, it only returns the balance of the vault. The balance is used to determine the number of shares that should be minted when depositing funds into the vault and the number of shares that should be burned when withdrawing funds from it.Since most of the funds will be located in the strategy, the vault's balance will be very low. Some of the issues that arise from this:
You can't deposit to a vault that already minted shares but has no balance of the underlying token:
balance == 0
andtotalSupply == 10
)pool == balance()
)You get more shares than you should
balance == 0
andtotalSupply == 10
)1
instead of0
.5 * 10 / 1 == 50
shares: https://github.com/code-423n4/2022-04-badger-citadel/blob/main/src/StakedCitadel.sol#L890Now, the vault received 15 tokens. 10 from Alice and 5 from Bob. But Alice only has 10 shares while Bob has 50. Thus, Bob can withdraw more tokens than he should be able to.
It simply breaks the whole accounting of the vault.
Proof of Concept
The comment says that it should be vault's + strategy's balance: https://github.com/code-423n4/2022-04-badger-citadel/blob/main/src/StakedCitadel.sol#L291-L295
Here's another vault from the badger team where the function is implemented correctly: https://github.com/Badger-Finance/badger-vaults-1.5/blob/main/contracts/Vault.sol#L262
Tools Used
none
Recommended Mitigation Steps
Add the strategy's balance to the return value of the
balance()
function like here.