Light ModeLight
Light ModeDark

One Bug Per Day

One H/M every day from top Wardens

Checkmark

Join over 1130 wardens!

Checkmark

Receive the email at any hour!

Ad

depositWithPermit and mintWithPermit are allowed to be called by permit creator only

mediumCode4rena

Lines of code

https://github.com/GenerationSoftware/pt-v5-vault/blob/b1deb5d494c25f885c34c83f014c8a855c5e2749/src/Vault.sol#L435

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.

https://github.com/GenerationSoftware/pt-v5-vault/blob/b1deb5d494c25f885c34c83f014c8a855c5e2749/src/Vault.sol#L427-L437

solidity
function 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

solidity
function _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.

solidity
function 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