58773 sc medium in stargate incorrect allocation cap accounting leading to unnecessary dos
Submitted on Nov 4th 2025 at 12:53:01 UTC by @aman for Audit Comp | Alchemix V3
Report ID: #58773
Report Type: Smart Contract
Report severity: Medium
Target: https://github.com/alchemix-finance/v3-poc/blob/immunefi_audit/src/strategies/optimism/StargateEthPoolStrategy.sol
Impacts:
Contract fails to deliver promised returns, but doesn't lose value
Description
Brief/Intro
While allocating deposits into the Stargate strategy, the implementation removes the dust amount from the provided deposit value and only deposits the remaining amount into the strategy.However, the vault still records the full provided amount (including the removed dust) in the allocation caps mapping.
As a result, the stored allocation value becomes inaccurate, leading to a situation where the system incorrectly reports that the allocation cap has been reached even though the actual deposited amount is lower.
Vulnerability Details
To understand this behavior, let’s first examine the Vault’s allocation flow: allocate -> allocateInternal
/v3-poc/lib/vault-v2/src/VaultV2.sol:570
570: function allocateInternal(address adapter, bytes memory data, uint256 assets) internal {
571: (bytes32[] memory ids, int256 change) = IAdapter(adapter).allocate(data, assets, msg.sig, msg.sender);
572:
573: for (uint256 i; i < ids.length; i++) {
574: Caps storage _caps = caps[ids[i]];
575: _caps.allocation = (int256(_caps.allocation) + change).toUint256();
576:
577: require(_caps.absoluteCap > 0, ErrorsLib.ZeroAbsoluteCap());
578: require(_caps.allocation <= _caps.absoluteCap, ErrorsLib.AbsoluteCapExceeded());
579: require(
580: _caps.relativeCap == WAD || _caps.allocation <= firstTotalAssets.mulDivDown(_caps.relativeCap, WAD),
581: ErrorsLib.RelativeCapExceeded()
582: );
583: }
584: emit EventsLib.Allocate(msg.sender, adapter, assets, ids, change);
585: }
586: At line 571, the value stored in change is added to caps.allocation.
Now, let’s take a closer look at the Stargate strategy:
Here we can observe that at line 47, the dust is subtracted from the provided amount before depositing into the strategy, while at line 52, the function returns the original amount (including the dust).
By combining both code snippets, we can summarize the behavior as follows:
Admin allocates:
3999999999999999996After removing dust:
3999999000000000000The
_allocatefunction still returns3999999999999999996, and the vault recordscaps.allocation = 3999999999999999996.Even after a full
deallocation, the vault still showscaps.allocation = 999999999996, which corresponds exactly to thedustamount stored in step 3.
Impact Details
Due to incorrect caps.allocation calculation, the vault reports inaccurate cap values, which can cause unexpected reverts and potential DoS during allocation.
References
StargateEthPoolStrategy.sol#L46-L52
Proof of Concept
Proof of Concept
Add Following file to test/strategies Dir with the name POC.t.sol :
Run With Command : forge test --match-test test_allocation_caps -vvv --decode-internal
Was this helpful?