#36532 [SC-Medium] Frontrun to invalidate collateralizable approval signature
Submitted on Nov 5th 2024 at 09:58:52 UTC by @trtrth for Audit Comp | Anvil
Report ID: #36532
Report Type: Smart Contract
Report severity: Medium
Target: https://etherscan.io/address/0xd042C267758eDDf34B481E1F539d637e41db3e5a
Impacts:
Griefing (e.g. no profit motive for an attacker, but damage to the users or the protocol)
Description
Brief/Intro
The contract `TimeBasedCollateralPool` allows a staker to stake using the collateralizable approval signature, which is verified by `CollateralVault` contract. In case a staker tries to stake using collateralizable approval signature, a malicious actor can frontrun with the staker's valid signature, which then cause the staker's transaction to be reverted.
Vulnerability Details
The function `TimeBasedCollateralPool::stake()` calls function `CollateralVault::modifyCollateralizableTokenAllowanceWithSignature()` if the signature is passed from caller:
```solidity function stake(IERC20 _token, uint256 _amount, bytes calldata _collateralizableApprovalSignature) external withEligibleAccountTokensReleased(msg.sender, address(_token)) returns (uint256) { if (_collateralizableApprovalSignature.length > 0) { @> collateral.modifyCollateralizableTokenAllowanceWithSignature( msg.sender, address(this), address(_token), Pricing.safeCastToInt256(_amount), _collateralizableApprovalSignature ); }
```
The function `CollateralVault::modifyCollateralizableTokenAllowanceWithSignature()` will update the account's collateralizable allowance if the given signature is valid without any restrictions for the caller. The transaction effectively increases nonce for the signer account.
So there will be cases when a malicious actor front-runs a staker by a transaction calling `modifyCollateralizableTokenAllowanceWithSignature()` with the signature collected from staker's `stake()` transaction. As a result, the `stake()` transaction will be reverted because of invalid nonce
Impact Details
Griefing, since the attacker makes no profit and the staker can submit another transaction to successfully stakes
References
https://github.com/AcronymFoundation/anvil-contracts/blob/1bbe04bb6f1aa1beea0ebf55e1bad67da3aa0f87/contracts/CollateralVault.sol#L294-L311
https://github.com/AcronymFoundation/anvil-contracts/blob/1bbe04bb6f1aa1beea0ebf55e1bad67da3aa0f87/contracts/CollateralVault.sol#L793-L823
https://github.com/AcronymFoundation/anvil-contracts/blob/1bbe04bb6f1aa1beea0ebf55e1bad67da3aa0f87/contracts/CollateralVault.sol#L587-L630
https://github.com/AcronymFoundation/anvil-contracts/blob/1bbe04bb6f1aa1beea0ebf55e1bad67da3aa0f87/contracts/TimeBasedCollateralPool.sol#L648-L663
Proof of Concept
Proof of Concept
This PoC is created as a Solidity test file under repository https://github.com/AcronymFoundation/anvil-contracts/tree/main
```solidity pragma solidity 0.8.25;
import "forge-std/Test.sol"; import {TimeBasedCollateralPool} from "src/TimeBasedCollateralPool.sol"; import {CollateralVault} from "src/CollateralVault.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
contract PocTest is Test { CollateralVault collateralVault = CollateralVault(0x5d2725fdE4d7Aa3388DA4519ac0449Cc031d675f);
}
```
The test would pass since the call at step 7 fails due to InvalidSignature error