Skip to content
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

Pool 2870 update prizepool vault to be able to redistribute prizes #14

Merged
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,10 @@
[submodule "lib/v5-prize-pool"]
path = lib/v5-prize-pool
url = https://github.com/pooltogether/v5-prize-pool
branch = pool-2870-update-prizepool-vault-to-be-able-to-redistribute-prizes
[submodule "lib/owner-manager-contracts"]
path = lib/owner-manager-contracts
url = https://github.com/pooltogether/owner-manager-contracts
[submodule "lib/v5-vrgda-claimer"]
path = lib/v5-vrgda-claimer
url = https://github.com/pooltogether/v5-vrgda-claimer
[submodule "lib/ring-buffer-lib"]
path = lib/ring-buffer-lib
url = https://github.com/pooltogether/ring-buffer-lib
Expand Down
1 change: 0 additions & 1 deletion lib/v5-vrgda-claimer
Submodule v5-vrgda-claimer deleted from 9d35e2
1 change: 0 additions & 1 deletion remappings.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ v5-liquidator-libraries/=lib/v5-liquidator/src/libraries/
v5-liquidator-test/=lib/v5-liquidator/test/
v5-prize-pool/=lib/v5-prize-pool/src/
v5-twab-controller/=lib/v5-twab-controller/src/
v5-vrgda-claimer/=lib/v5-vrgda-claimer/src/

src/=src/
test/=test/
78 changes: 67 additions & 11 deletions src/Vault.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { LiquidationPair } from "v5-liquidator/LiquidationPair.sol";
import { ILiquidationSource } from "v5-liquidator-interfaces/ILiquidationSource.sol";
import { PrizePool } from "v5-prize-pool/PrizePool.sol";
import { TwabController } from "v5-twab-controller/TwabController.sol";
import { Claimer } from "v5-vrgda-claimer/Claimer.sol";
import { Hook } from "src/interfaces/IVaultHooks.sol";

/// @notice Emitted when the TWAB controller is set to the zero address
error TwabControllerZeroAddress();
Expand Down Expand Up @@ -133,7 +133,7 @@ contract Vault is ERC4626, ERC20Permit, ILiquidationSource, Ownable {
TwabController twabController,
IERC4626 indexed yieldVault,
PrizePool indexed prizePool,
Claimer claimer,
address claimer,
address yieldFeeRecipient,
uint256 yieldFeePercentage,
address owner
Expand All @@ -144,7 +144,14 @@ contract Vault is ERC4626, ERC20Permit, ILiquidationSource, Ownable {
* @param previousClaimer Address of the previous claimer
* @param newClaimer Address of the new claimer
*/
event ClaimerSet(Claimer previousClaimer, Claimer newClaimer);
event ClaimerSet(address previousClaimer, address newClaimer);

/**
* @notice Emitted when an account sets a new hook
* @param account The account whose hooks are being configured
* @param hook The hook being set
*/
event HookSet(address account, Hook hook);

/**
* @notice Emitted when a new LiquidationPair has been set.
Expand Down Expand Up @@ -195,7 +202,7 @@ contract Vault is ERC4626, ERC20Permit, ILiquidationSource, Ownable {
PrizePool private immutable _prizePool;

/// @notice Address of the claimer.
Claimer private _claimer;
address private _claimer;

/// @notice Address of the LiquidationPair used to liquidate yield for prize token.
LiquidationPair private _liquidationPair;
Expand All @@ -218,6 +225,9 @@ contract Vault is ERC4626, ERC20Permit, ILiquidationSource, Ownable {
/// @notice Fee precision denominated in 9 decimal places and used to calculate yield fee percentage.
uint256 private constant FEE_PRECISION = 1e9;

/// @notice Allows users to add hooks that execute code when prizes are won
mapping(address => Hook) internal _hooks;

/* ============ Constructor ============ */

/**
Expand All @@ -241,7 +251,7 @@ contract Vault is ERC4626, ERC20Permit, ILiquidationSource, Ownable {
TwabController twabController_,
IERC4626 yieldVault_,
PrizePool prizePool_,
Claimer claimer_,
address claimer_,
address yieldFeeRecipient_,
uint256 yieldFeePercentage_,
address _owner
Expand Down Expand Up @@ -569,20 +579,47 @@ contract Vault is ERC4626, ERC20Permit, ILiquidationSource, Ownable {
* - caller can be any address except claimer address
* @param _tier Tier to claim prize for
* @param _winners Addresses of the winners to claim prizes
* @param _prizes The prizes to claim for each winner
* @param _prizeIndices The prizes to claim for each winner
* @param _feePerClaim Fee to be charged per prize claim
* @param _claimFeeRecipient Address that will receive `_claimFee` amount
*/
function claimPrizes(
uint8 _tier,
address[] calldata _winners,
uint32[][] calldata _prizes,
uint32[][] calldata _prizeIndices,
uint96 _feePerClaim,
address _claimFeeRecipient
) external returns (uint256) {
if (msg.sender != address(_claimer)) revert CallerNotClaimer(msg.sender, address(_claimer));

return _prizePool.claimPrizes(_tier, _winners, _prizes, _feePerClaim, _claimFeeRecipient);
uint totalPrizes;

for (uint w = 0; w < _winners.length; w++) {
uint prizeIndicesLength = _prizeIndices[w].length;
for (uint p = 0; p < prizeIndicesLength; p++) {
totalPrizes += _claimPrize(_winners[w], _tier, _prizeIndices[w][p], _feePerClaim, _claimFeeRecipient);
}
}

return totalPrizes;
}

function _claimPrize(address _winner, uint8 _tier, uint32 _prizeIndex, uint96 _fee, address _feeRecipient) internal returns (uint256) {
Hook memory hook = _hooks[_winner];
address recipient;
if (hook.useBeforeClaimPrize) {
recipient = hook.hooks.beforeClaimPrize(_winner, _tier, _prizeIndex);
} else {
recipient = _winner;
}

uint prizeTotal = _prizePool.claimPrize(_winner, _tier, _prizeIndex, recipient, _fee, _feeRecipient);

if (hook.useAfterClaimPrize) {
hook.hooks.afterClaimPrize(_winner, _tier, _prizeIndex, prizeTotal - _fee, recipient);
}
trmid marked this conversation as resolved.
Show resolved Hide resolved

return prizeTotal;
}

/**
Expand All @@ -609,14 +646,33 @@ contract Vault is ERC4626, ERC20Permit, ILiquidationSource, Ownable {
* @param claimer_ Address of the claimer
* return address New claimer address
*/
function setClaimer(Claimer claimer_) external onlyOwner returns (address) {
Claimer _previousClaimer = _claimer;
function setClaimer(address claimer_) external onlyOwner returns (address) {
address _previousClaimer = _claimer;
_setClaimer(claimer_);

emit ClaimerSet(_previousClaimer, claimer_);
return address(claimer_);
}

/**
* @notice Sets the hooks for a winner
* @param hook The hook to set.
*/
function setHooks(Hook memory hook) external {
_hooks[msg.sender] = hook;

emit HookSet(msg.sender, hook);
}

/**
* @notice Gets the hooks for the given user
* @param _account The user to retrieve the hooks for
* @return The hooks for the given user
*/
function getHooks(address _account) external view returns (Hook memory) {
return _hooks[_account];
}

/**
* @notice Set liquidationPair.
* @dev We reset approval of the previous liquidationPair and approve max for new one.
Expand Down Expand Up @@ -1075,7 +1131,7 @@ contract Vault is ERC4626, ERC20Permit, ILiquidationSource, Ownable {
* @notice Set claimer address.
* @param claimer_ Address of the claimer
*/
function _setClaimer(Claimer claimer_) internal {
function _setClaimer(address claimer_) internal {
_claimer = claimer_;
}

Expand Down
3 changes: 1 addition & 2 deletions src/VaultFactory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import { IERC20, IERC4626 } from "openzeppelin/token/ERC20/extensions/ERC4626.so
import { LiquidationPair } from "v5-liquidator/LiquidationPair.sol";
import { PrizePool } from "v5-prize-pool/PrizePool.sol";
import { TwabController } from "v5-twab-controller/TwabController.sol";
import { Claimer } from "v5-vrgda-claimer/Claimer.sol";

import { Vault } from "./Vault.sol";

Expand Down Expand Up @@ -55,7 +54,7 @@ contract VaultFactory {
TwabController _twabController,
IERC4626 _yieldVault,
PrizePool _prizePool,
Claimer _claimer,
address _claimer,
address _yieldFeeRecipient,
uint256 _yieldFeePercentage,
address _owner
Expand Down
30 changes: 30 additions & 0 deletions src/interfaces/IVaultHooks.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.17;

struct Hook {
/// @notice If true, the vault will call the beforeClaimPrize fxn on the hook.
bool useBeforeClaimPrize;
/// @notice If true, the vault will call the afterClaimPrize on the hook
bool useAfterClaimPrize;
/// @notice The address of the smart contarct implementing the hooks
IVaultHooks hooks;
}
trmid marked this conversation as resolved.
Show resolved Hide resolved

/// @notice Allows winners to attach smart contract hooks to their prize winnings
interface IVaultHooks {

/// @notice Triggered before the prize pool claim prize function is called.
/// @param winner The user who won the prize and for whom this hook is attached
/// @param tier The tier of the prize
/// @param prizeIndex The index of the prize in the tier
/// @return The address of the recipient of the prize
function beforeClaimPrize(address winner, uint8 tier, uint32 prizeIndex) external returns (address);

/// @notice Triggered after the prize pool claim prize function is called.
/// @param winner The user who won the prize and for whom this hook is attached
/// @param tier The tier of the prize
/// @param prizeIndex The index of the prize
/// @param payout The amount of tokens paid out to the recipient
/// @param recipient The recipient of the prize
function afterClaimPrize(address winner, uint8 tier, uint32 prizeIndex, uint256 payout, address recipient) external returns (bool);
}
4 changes: 2 additions & 2 deletions test/contracts/mock/Vault.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.17;

import { IERC20, IERC4626, Claimer, PrizePool, TwabController, Vault } from "src/Vault.sol";
import { IERC20, IERC4626, PrizePool, TwabController, Vault } from "src/Vault.sol";

contract VaultMock is Vault {
constructor(
Expand All @@ -11,7 +11,7 @@ contract VaultMock is Vault {
TwabController twabController_,
IERC4626 yieldVault_,
PrizePool prizePool_,
Claimer claimer_,
address claimer_,
address yieldFeeRecipient_,
uint256 yieldFeePercentage_,
address _owner
Expand Down
3 changes: 1 addition & 2 deletions test/fuzz/Vault.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import { Strings } from "openzeppelin/utils/Strings.sol";
import { LiquidationPair } from "v5-liquidator/LiquidationPair.sol";
import { PrizePool } from "v5-prize-pool/PrizePool.sol";
import { TwabController } from "v5-twab-controller/TwabController.sol";
import { Claimer } from "v5-vrgda-claimer/Claimer.sol";

import { Vault } from "src/Vault.sol";

Expand Down Expand Up @@ -64,7 +63,7 @@ contract VaultFuzzTest is ERC4626Test, Helpers {
twabController,
yieldVault,
PrizePool(address(prizePool)),
Claimer(address(0x2faD9255711A4d22C35a003b3E723D9271aeA51d)),
address(0x2faD9255711A4d22C35a003b3E723D9271aeA51d),
address(this),
0,
address(this)
Expand Down
Loading