depositWithPermit and mintWithPermit are allowed to be called by permit creator only
mediumLines of code
Vulnerability details
Impact
depositWithPermit and mintWithPermit are allowed to be called by permit creator only. No any other contracts will be able to execute these function on behalf of signer.
Proof of Concept
depositWithPermit function allows to provide signed permit in order to receive approve and deposit funds into the vault.
solidityfunction depositWithPermit( uint256 _assets, address _receiver, uint256 _deadline, uint8 _v, bytes32 _r, bytes32 _s ) external returns (uint256) { _permit(IERC20Permit(asset()), msg.sender, address(this), _assets, _deadline, _v, _r, _s); return deposit(_assets, _receiver); }
This function calls _permit and pass msg.sender as _owner to that function.
https://github.com/GenerationSoftware/pt-v5-vault/blob/b1deb5d494c25f885c34c83f014c8a855c5e2749/src/Vault.sol#L1093-L1104
solidityfunction _permit( IERC20Permit _asset, address _owner, address _spender, uint256 _assets, uint256 _deadline, uint8 _v, bytes32 _r, bytes32 _s ) internal { _asset.permit(_owner, _spender, _assets, _deadline, _v, _r, _s); }
This means that signer can be only the same person that called depositWithPermit function.
However the purpose of permit is to allow someone to sign approve signature, so that this signature can be used by another contract to call some function on behalf of signer.
In this case, anyone should be able to sign permit for the vault, and vault should check that _receiver is same who signed permit.
Tools Used
VsCode
Recommended Mitigation Steps
Use _receiver instead of msg.sender.
solidityfunction depositWithPermit( uint256 _assets, address _receiver, uint256 _deadline, uint8 _v, bytes32 _r, bytes32 _s ) external returns (uint256) { _permit(IERC20Permit(asset()), _receiver, address(this), _assets, _deadline, _v, _r, _s); return deposit(_assets, _receiver); }
Assessed type
Error
