Closed sherlock-admin3 closed 3 months ago
It's a user error issue, If they deposit more than cap.
I don't agree with the decision:
TrancheRouter
or the Tranche
spenders. I think these type of checks should be performed on the smart contract side.@z3s, please re-consider.
@z3s, additionally, the supply caps of the protocols are not static. Moreover, they are dynamic. If the user's transaction is front-run, for instance, and in these blocks that skip the user's transaction, the particular protocol's supply cap is updated, then the user's funds will be lost, even if the user checked the supply cap limits prior to depositing.
Taking into account my new arguments, could you please escalate this one?
Escalate @z3s I believe it should be checked on the smart contract side, and it's a fix worth implementing. As @BiasedMerc mentioned in the Discord channel, the victim user (e.g., a whale) can be griefed if his deposit happens around the time the Kelp DAO or Puffer protocols decide to update the supply cap (specifically, if they decrease the single-transaction deposit limit). Then this will make the Napier Adapters shares unfair, and it'll lock the user's funds permanently.
KungFuPanda
medium
When there's a protocol-specific limit of the underlyingAmount that can be supplied through a single deposit, the remainder of the underlyingAmount that was charged from the user is not sent back to the user
Summary
It's a common practice for a protocol to set a limit of amount that can be deposited once per a call.
Usually that is worth ~9000 WETH, but it depends on the protocol, and this is not a CONSTANT, i.e. it can be changed after the Napier adapter contracts are deployed and functioning.
Vulnerability Detail
If the user decides to deposit a large amount AT ONCE, the real deposit that the Napier adapter will send to the protocol will be capped at the max limit that the protocol allows. This is usually fine, however there're no refunds that will send the user his funds back.
The protocol's limit is usually DYNAMIC, so under some conditions it can become a reaslistic and relatively small amount.
Impact
User's funds will be stuck in the contract, and the real shares of a single 1 wei that the Adapter holds on the behalf of his users will be more expensive that in reality a 1 wei share is worth in the Kelp/PufETH pool.
Code Snippet
Due to issues with running
forge test
in thenapier-uups-adapters
repo. (No artifacts found for contractCreate2TrancheLib
...), I'm not providing a PoC, unfortunately. Apologies for that.But to give your an idea here I'm supplying the code snippets of where the problem comes from:
№1::
↑ Here the funds are charged from the owner, and notice that there're no prior checks whether this deposit will exceed the target protocol's deposit limit.
The user may directly use the
Tranche
contract, but most users will use the router.№2::
↑ Here the funds are transferred from the router / the caller (if the user calls this contract directly), then the fee is decucted and the leftover is transferred to the target adapter.
Please notice that the full amount of the
underlyingToken
is transferred to the adapter, and no deposit limit caps are taken into account.№3::
↑ As you can see, the child (overriden)
_claim
function is called, but there's no prior accounting for a SINGLE-DEPOSIT depositing limit that the destination protocol might have.And there're no refunds either. Though the user's minted shares correspond to the amount that was charged from the user in a proper manner, but the actual amount that will be deposited into the pool is lower than that, and the worth of a 1 wei share at the end will be less than the Adapter contract expects.
№4::
↑
Here you can see the deposit amount is capped at the MAX amount that the
PUFFER_DEPOSITOR
allows per 1 single deposit.Notice that this amount is NOT constant, and it can be changed by the admin or a permissioned role user of a protocol that the Adapter corresponds for.
Tool used
Manual Review
Recommendation
Consider adding a mechanism of returning the user the remainder of a deposit if the ACTUAL deposited amount is LESS than the charged amount.
References
https://github.com/sherlock-audit/2024-05-napier-update/blob/main/napier-uups-adapters/src/adapters/puffer/PufETHAdapter.sol#L63C5-L87C6
https://github.com/sherlock-audit/2024-05-napier-update/blob/c31af59c6399182fd04b40530d79d98632d2bfa7/napier-v1/src/Tranche.sol#L163C5-L213C6
https://github.com/sherlock-audit/2024-05-napier-update/blob/c31af59c6399182fd04b40530d79d98632d2bfa7/napier-v1/src/Tranche.sol#L202
https://github.com/sherlock-audit/2024-05-napier-update/blob/main/napier-uups-adapters/src/adapters/BaseLSTAdapterUpgradeable.sol#L158