@@ -16,7 +16,7 @@ import { IClaimable } from "pt-v5-claimable-interface/interfaces/IClaimable.sol"
16
16
import { VaultHooks } from "./interfaces/IVaultHooks.sol " ;
17
17
18
18
/**
19
- * @title PoolTogether V5 Vault
19
+ * @title PoolTogether V5 Vault (Version 2)
20
20
* @author PoolTogether Inc. & G9 Software Inc.
21
21
* @notice Vault extends the ERC4626 standard and is the entry point for users interacting with a V5 pool.
22
22
* Users deposit an underlying asset (i.e. USDC) in this contract and receive in exchange an ERC20 token
@@ -25,7 +25,7 @@ import { VaultHooks } from "./interfaces/IVaultHooks.sol";
25
25
* This yield is sold for prize tokens (i.e. POOL) via the Liquidator and captured by the PrizePool to be awarded to depositors.
26
26
* @dev Balances are stored in the TwabController contract.
27
27
*/
28
- contract Vault is IERC4626 , ERC20Permit , ILiquidationSource , IClaimable , Ownable {
28
+ contract VaultV2 is IERC4626 , ERC20Permit , ILiquidationSource , IClaimable , Ownable {
29
29
using Math for uint256 ;
30
30
using SafeCast for uint256 ;
31
31
using SafeERC20 for IERC20 ;
@@ -301,6 +301,23 @@ contract Vault is IERC4626, ERC20Permit, ILiquidationSource, IClaimable, Ownable
301
301
/// @notice Emitted when a prize is claimed for the zero address.
302
302
error ClaimRecipientZeroAddress ();
303
303
304
+ /**
305
+ * @notice Emitted when the caller of a permit function is not the owner of the assets being permitted.
306
+ * @param caller The address of the caller
307
+ * @param owner The address of the owner
308
+ */
309
+ error PermitCallerNotOwner (address caller , address owner );
310
+
311
+ /**
312
+ * @notice Emitted when a permit call on the underlying asset failed to set the spending allowance.
313
+ * @dev This is likely thrown when the underlying asset does not support permit, but has a fallback function.
314
+ * @param owner The owner of the assets
315
+ * @param spender The spender of the assets
316
+ * @param amount The amount of assets permitted
317
+ * @param allowance The allowance after the permit was called
318
+ */
319
+ error PermitAllowanceNotSet (address owner , address spender , uint256 amount , uint256 allowance );
320
+
304
321
/* ============ Modifiers ============ */
305
322
306
323
/// @notice Modifier reverting if the Vault is under-collateralized.
@@ -528,7 +545,17 @@ contract Vault is IERC4626, ERC20Permit, ILiquidationSource, IClaimable, Ownable
528
545
bytes32 _r ,
529
546
bytes32 _s
530
547
) external returns (uint256 ) {
531
- _permit (IERC20Permit (address (_asset)), _owner, address (this ), _assets, _deadline, _v, _r, _s);
548
+ if (_owner != msg .sender ) {
549
+ revert PermitCallerNotOwner (msg .sender , _owner);
550
+ }
551
+
552
+ IERC20Permit (address (_asset)).permit (_owner, address (this ), _assets, _deadline, _v, _r, _s);
553
+
554
+ uint256 _allowance = _asset.allowance (_owner, address (this ));
555
+ if (_allowance != _assets) {
556
+ revert PermitAllowanceNotSet (_owner, address (this ), _assets, _allowance);
557
+ }
558
+
532
559
return _depositAssets (_assets, _owner, _owner, false );
533
560
}
534
561
@@ -670,8 +697,7 @@ contract Vault is IERC4626, ERC20Permit, ILiquidationSource, IClaimable, Ownable
670
697
671
698
_onlyVaultCollateralized (_depositedAssets, _withdrawableAssets);
672
699
673
- uint256 _availableYield = _withdrawableAssets -
674
- _convertToAssets (_depositedAssets, _depositedAssets, _withdrawableAssets, Math.Rounding.Down);
700
+ uint256 _availableYield = _withdrawableAssets - _depositedAssets;
675
701
676
702
if (_shares > _availableYield) revert YieldFeeGTAvailableYield (_shares, _availableYield);
677
703
if (_shares > _yieldFeeShares) revert YieldFeeGTAvailableShares (_shares, _yieldFeeShares);
@@ -1073,38 +1099,6 @@ contract Vault is IERC4626, ERC20Permit, ILiquidationSource, IClaimable, Ownable
1073
1099
_collateralAssets == 0 ? 0 : _shares.mulDiv (_collateralAssets, _depositedAssets, _rounding);
1074
1100
}
1075
1101
1076
- /**
1077
- * @notice Convert Vault shares to YieldVault shares.
1078
- * @param _shares Vault shares to convert
1079
- * @param _depositedAssets Assets deposited into the YieldVault
1080
- * @param _withdrawableAssets Assets withdrawable from the YieldVault
1081
- * @param _maxRedeemableYVShares Maximum amount of shares that can be redeemed from the YieldVault
1082
- * @param _rounding Rounding mode (i.e. down or up)
1083
- * @return uint256 YieldVault shares
1084
- */
1085
- function _convertSharesToYVShares (
1086
- uint256 _shares ,
1087
- uint256 _depositedAssets ,
1088
- uint256 _withdrawableAssets ,
1089
- uint256 _maxRedeemableYVShares ,
1090
- Math.Rounding _rounding
1091
- ) internal view returns (uint256 ) {
1092
- if (_shares == 0 ) {
1093
- return _shares;
1094
- }
1095
-
1096
- if (_depositedAssets == 0 ) {
1097
- return _yieldVault.convertToShares (_shares);
1098
- }
1099
-
1100
- uint256 _redeemableShares = _isVaultCollateralized (_depositedAssets, _withdrawableAssets)
1101
- ? _depositedAssets // shares are backed 1:1 by assets, no need to convert to YieldVault shares
1102
- : _maxRedeemableYVShares;
1103
-
1104
- return
1105
- _redeemableShares == 0 ? 0 : _shares.mulDiv (_redeemableShares, _depositedAssets, _rounding);
1106
- }
1107
-
1108
1102
/* ============ Max / Preview Functions ============ */
1109
1103
1110
1104
/**
@@ -1317,11 +1311,9 @@ contract Vault is IERC4626, ERC20Permit, ILiquidationSource, IClaimable, Ownable
1317
1311
uint256 _yieldVaultShares;
1318
1312
1319
1313
if (! _vaultCollateralized) {
1320
- _yieldVaultShares = _convertSharesToYVShares (
1321
- _shares,
1322
- _totalSupply (),
1323
- _totalAssets (),
1314
+ _yieldVaultShares = _shares.mulDiv (
1324
1315
_yieldVault.maxRedeem (address (this )),
1316
+ _totalSupply (),
1325
1317
Math.Rounding.Down
1326
1318
);
1327
1319
}
@@ -1349,32 +1341,6 @@ contract Vault is IERC4626, ERC20Permit, ILiquidationSource, IClaimable, Ownable
1349
1341
return _assets;
1350
1342
}
1351
1343
1352
- /* ============ Permit Functions ============ */
1353
-
1354
- /**
1355
- * @notice Approve `_spender` to spend `_assets` of `_owner`'s `_permitAsset` via signature.
1356
- * @param _permitAsset Address of the asset to approve
1357
- * @param _owner Address of the owner of the asset
1358
- * @param _spender Address of the spender of the asset
1359
- * @param _assets Amount of assets to approve
1360
- * @param _deadline Timestamp after which the approval is no longer valid
1361
- * @param _v V part of the secp256k1 signature
1362
- * @param _r R part of the secp256k1 signature
1363
- * @param _s S part of the secp256k1 signature
1364
- */
1365
- function _permit (
1366
- IERC20Permit _permitAsset ,
1367
- address _owner ,
1368
- address _spender ,
1369
- uint256 _assets ,
1370
- uint256 _deadline ,
1371
- uint8 _v ,
1372
- bytes32 _r ,
1373
- bytes32 _s
1374
- ) internal {
1375
- _permitAsset.permit (_owner, _spender, _assets, _deadline, _v, _r, _s);
1376
- }
1377
-
1378
1344
/* ============ State Functions ============ */
1379
1345
1380
1346
/**
0 commit comments