-
Notifications
You must be signed in to change notification settings - Fork 37
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implemented safety mechanisms around vault hooks #21
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -98,6 +98,12 @@ error LPZeroAddress(); | |
/// @param maxYieldFeePercentage The max yield fee percentage in integer format (this value is equal to 1 in decimal format) | ||
error YieldFeePercentageGTPrecision(uint256 yieldFeePercentage, uint256 maxYieldFeePercentage); | ||
|
||
error BeforeClaimPrizeFailed(bytes reason); | ||
|
||
error AfterClaimPrizeFailed(bytes reason); | ||
|
||
uint256 constant HOOK_GAS = 150_000; | ||
|
||
/** | ||
* @title PoolTogether V5 Vault | ||
* @author PoolTogether Inc Team, Generation Software Team | ||
|
@@ -199,6 +205,13 @@ contract Vault is ERC4626, ERC20Permit, ILiquidationSource, Ownable { | |
*/ | ||
event RecordedExchangeRate(uint256 exchangeRate); | ||
|
||
event ClaimFailed( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add Natspec doc. |
||
address indexed winner, | ||
uint8 indexed tier, | ||
uint32 indexed prizeIndex, | ||
bytes reason | ||
); | ||
|
||
/* ============ Variables ============ */ | ||
|
||
/// @notice Address of the TwabController used to keep track of balances. | ||
|
@@ -616,21 +629,28 @@ contract Vault is ERC4626, ERC20Permit, ILiquidationSource, Ownable { | |
uint32[][] calldata _prizeIndices, | ||
uint96 _feePerClaim, | ||
address _feeRecipient | ||
) external returns (uint256) { | ||
if (msg.sender != _claimer) revert CallerNotClaimer(msg.sender, _claimer); | ||
|
||
) external onlyClaimer returns (uint256) { | ||
uint totalPrizes; | ||
|
||
for (uint w = 0; w < _winners.length; w++) { | ||
uint prizeIndicesLength = _prizeIndices[w].length; | ||
for (uint p = 0; p < prizeIndicesLength; p++) { | ||
totalPrizes += _claimPrize( | ||
try this.claimPrize_INTERNAL_USE_ONLY( | ||
_winners[w], | ||
_tier, | ||
_prizeIndices[w][p], | ||
_feePerClaim, | ||
_feeRecipient | ||
); | ||
) returns (uint256 prize) { | ||
totalPrizes += prize; | ||
} catch (bytes memory reason) { | ||
emit ClaimFailed( | ||
_winners[w], | ||
_tier, | ||
_prizeIndices[w][p], | ||
reason | ||
); | ||
} | ||
} | ||
} | ||
|
||
|
@@ -1038,6 +1058,15 @@ contract Vault is ERC4626, ERC20Permit, ILiquidationSource, Ownable { | |
} | ||
|
||
/* ============ Claim Functions ============ */ | ||
function claimPrize( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add Natspec doc. |
||
address _winner, | ||
uint8 _tier, | ||
uint32 _prizeIndex, | ||
uint96 _fee, | ||
address _feeRecipient | ||
) external onlyClaimer returns (uint256) { | ||
return this.claimPrize_INTERNAL_USE_ONLY(_winner, _tier, _prizeIndex, _fee, _feeRecipient); | ||
} | ||
|
||
/** | ||
* @notice Claim prize for `_winner`. | ||
|
@@ -1048,18 +1077,24 @@ contract Vault is ERC4626, ERC20Permit, ILiquidationSource, Ownable { | |
* @param _feeRecipient Address that will receive the fee | ||
* @return uint256 The total prize amount claimed | ||
*/ | ||
function _claimPrize( | ||
function claimPrize_INTERNAL_USE_ONLY( | ||
address _winner, | ||
uint8 _tier, | ||
uint32 _prizeIndex, | ||
uint96 _fee, | ||
address _feeRecipient | ||
) internal returns (uint256) { | ||
) external returns (uint256) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should be There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It has to be external because of the |
||
assert(msg.sender == address(this)); | ||
|
||
VaultHooks memory hooks = _hooks[_winner]; | ||
address recipient; | ||
|
||
if (hooks.useBeforeClaimPrize) { | ||
recipient = hooks.implementation.beforeClaimPrize(_winner, _tier, _prizeIndex); | ||
try hooks.implementation.beforeClaimPrize{gas: HOOK_GAS}(_winner, _tier, _prizeIndex, _fee, _feeRecipient) returns (address result) { | ||
recipient = result; | ||
} catch (bytes memory reason) { | ||
revert BeforeClaimPrizeFailed(reason); | ||
} | ||
} else { | ||
recipient = _winner; | ||
} | ||
|
@@ -1074,13 +1109,10 @@ contract Vault is ERC4626, ERC20Permit, ILiquidationSource, Ownable { | |
); | ||
|
||
if (hooks.useAfterClaimPrize) { | ||
hooks.implementation.afterClaimPrize( | ||
_winner, | ||
_tier, | ||
_prizeIndex, | ||
prizeTotal - _fee, | ||
recipient | ||
); | ||
try hooks.implementation.afterClaimPrize{gas: HOOK_GAS}(_winner, _tier, _prizeIndex, prizeTotal - _fee, recipient) { | ||
} catch (bytes memory reason) { | ||
revert AfterClaimPrizeFailed(reason); | ||
} | ||
} | ||
|
||
return prizeTotal; | ||
|
@@ -1239,4 +1271,9 @@ contract Vault is ERC4626, ERC20Permit, ILiquidationSource, Ownable { | |
function _setYieldFeeRecipient(address yieldFeeRecipient_) internal { | ||
_yieldFeeRecipient = yieldFeeRecipient_; | ||
} | ||
|
||
modifier onlyClaimer() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add Natspec doc. |
||
if (msg.sender != _claimer) revert CallerNotClaimer(msg.sender, _claimer); | ||
_; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add Natspec docs.