Skip to content

Commit f17d041

Browse files
authored
Merge pull request #16 from GenerationSoftware/gen-1909-update-ocs-prize-hook-to-use-native-prize-redirects-instead
use native redirect for nft booster instead of double redirect
2 parents 2394177 + 50d473d commit f17d041

File tree

2 files changed

+21
-51
lines changed

2 files changed

+21
-51
lines changed

src/prize-hooks/examples/nft-chance-booster/NftChanceBoosterHook.sol

Lines changed: 13 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -39,15 +39,6 @@ contract NftChanceBoosterHook is IPrizeHooks {
3939
/// @param pickAttempts The number of times the hook tried to pick a winner
4040
event BoostedVaultWithPrize(address indexed prizePool, address indexed boostedVault, uint256 prizeAmount, uint256 pickAttempts);
4141

42-
/// @notice Emitted when an NFT holder wins a prize.
43-
/// @param nftWinner The NFT holder that won the prize
44-
/// @param vault The vault that the prize was won through
45-
/// @param donor The original winner of the prize before it was redirected
46-
/// @param tier The prize tier
47-
/// @param prizeIndex The prize index
48-
/// @param prizeAmount The amount of prize tokens won
49-
event PrizeWonByNftHolder(address indexed nftWinner, address indexed vault, address indexed donor, uint8 tier, uint32 prizeIndex, uint256 prizeAmount);
50-
5142
/// @notice The ERC721 token whose holders will have a chance to win prizes
5243
IERC721 public immutable nftCollection;
5344

@@ -72,9 +63,9 @@ contract NftChanceBoosterHook is IPrizeHooks {
7263
/// @notice Constructor to deploy the hook contract
7364
/// @param nftCollection_ The ERC721 token whose holders will have a chance to win prizes
7465
/// @param prizePool_ The prize pool that is awarding prizes
75-
/// @param boostedVault_ The The vault that is being boosted
76-
/// @param minTwabOverPrizePeriod_ The minimum TWAB that the selected winner must have over the prize
77-
/// period to win the prize; if set to zero, no balance is needed.
66+
/// @param boostedVault_ The The vault that is boosted if a winner cannot be determined
67+
/// @param minTwabOverPrizePeriod_ The minimum TWAB on the `boostedVault_` that the selected winner
68+
/// must have over the prize period to win the prize; if set to zero, no balance is needed.
7869
/// @param tokenIdLowerBound_ The lower bound of eligible NFT IDs (inclusive)
7970
/// @param tokenIdUpperBound_ The upper bound of eligible NFT IDs (inclusive)
8071
constructor(
@@ -105,7 +96,7 @@ contract NftChanceBoosterHook is IPrizeHooks {
10596
/// variance in the entropy for each prize so there can be multiple winners per draw.
10697
/// @dev Tries to select a winner until the call runs out of gas before reverting to the backup action of
10798
/// contributing the prize on behalf of the boosted vault.
108-
/// @dev Returns the winning token holder in data if successful or the number of pick attempts if not successful.
99+
/// @dev Returns the number of pick attempts used in the extra hook data.
109100
function beforeClaimPrize(address _winner, uint8 _tier, uint32 _prizeIndex, uint96, address) external view returns (address, bytes memory) {
110101
uint256 _tierStartTime;
111102
uint256 _tierEndTime;
@@ -143,8 +134,8 @@ contract NftChanceBoosterHook is IPrizeHooks {
143134
_recipientTwab = twabController.getTwabBetween(boostedVault, _ownerOfToken, _tierStartTime, _tierEndTime);
144135
}
145136
if (_recipientTwab >= minTwabOverPrizePeriod) {
146-
// The owner of the selected NFT will be awarded the prize in the `afterClaimPrize` callback.
147-
return (address(this), abi.encode(_ownerOfToken));
137+
// The prize will be redirected to the owner of the selected NFT
138+
return (_ownerOfToken, abi.encode(_pickAttempt + 1));
148139
}
149140
}
150141
}
@@ -155,19 +146,13 @@ contract NftChanceBoosterHook is IPrizeHooks {
155146

156147
/// @inheritdoc IPrizeHooks
157148
/// @dev If the recipient is set to the prize pool, the prize will be contributed on behalf of the vault
158-
/// that is being boosted. Otherwise if this contract received the prize, it will transfer it to the
159-
/// winner passed in through the extra hook data.
160-
function afterClaimPrize(address _winner, uint8 _tier, uint32 _prizeIndex, uint256 _prizeAmount, address _prizeRecipient, bytes memory _data) external {
161-
if (_prizeAmount > 0) {
162-
if (_prizeRecipient == address(prizePool)) {
163-
uint256 _pickAttempts = abi.decode(_data, (uint256));
164-
prizePool.contributePrizeTokens(boostedVault, _prizeAmount);
165-
emit BoostedVaultWithPrize(address(prizePool), boostedVault, _prizeAmount, _pickAttempts);
166-
} else if (_prizeRecipient == address(this)) {
167-
address _nftWinner = abi.decode(_data, (address));
168-
prizePool.prizeToken().safeTransfer(_nftWinner, _prizeAmount);
169-
emit PrizeWonByNftHolder(_nftWinner, msg.sender, _winner, _tier, _prizeIndex, _prizeAmount);
170-
}
149+
/// that is being boosted. Otherwise this hook does nothing since the prize will have already been redirected
150+
/// to the recipient.
151+
function afterClaimPrize(address, uint8, uint32, uint256 _prizeAmount, address _prizeRecipient, bytes memory _data) external {
152+
if (_prizeAmount > 0 && _prizeRecipient == address(prizePool)) {
153+
uint256 _pickAttempts = abi.decode(_data, (uint256));
154+
prizePool.contributePrizeTokens(boostedVault, _prizeAmount);
155+
emit BoostedVaultWithPrize(address(prizePool), boostedVault, _prizeAmount, _pickAttempts);
171156
}
172157
}
173158
}

test/prize-hooks/examples/nft-chance-booster/NftChanceBoosterHook.t.sol

Lines changed: 8 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -80,11 +80,10 @@ contract NftChanceBoosterHookTest is Test {
8080
for (uint256 i = 0; i < 1000; i++) {
8181
vm.mockCall(address(prizePool), abi.encodeWithSelector(PrizePool.getWinningRandomNumber.selector), abi.encode(randomNumber + i));
8282
(address recipient, bytes memory hookData) = callBeforeClaimPrize(0, 0);
83-
if (recipient == address(nftBooster)) {
84-
(address winner) = abi.decode(hookData, (address));
85-
if (winner == bob) numBobWins++;
86-
else if (winner == alice) numAliceWins++;
87-
}
83+
(uint256 pickAttempts) = abi.decode(hookData, (uint256));
84+
assertGt(pickAttempts, 0);
85+
if (recipient == bob) numBobWins++;
86+
else if (recipient == alice) numAliceWins++;
8887
}
8988
assertGt(numBobWins, 800);
9089
assertGt(numAliceWins, 50);
@@ -106,11 +105,10 @@ contract NftChanceBoosterHookTest is Test {
106105
for (uint256 i = 0; i < 1000; i++) {
107106
vm.mockCall(address(prizePool), abi.encodeWithSelector(PrizePool.getWinningRandomNumber.selector), abi.encode(randomNumber + i));
108107
(address recipient, bytes memory hookData) = callBeforeClaimPrize(0, 0);
109-
if (recipient == address(nftBooster)) {
110-
(address winner) = abi.decode(hookData, (address));
111-
if (winner == bob) numBobWins++;
112-
else if (winner == alice) numAliceWins++;
113-
}
108+
(uint256 pickAttempts) = abi.decode(hookData, (uint256));
109+
assertGt(pickAttempts, 0);
110+
if (recipient == bob) numBobWins++;
111+
else if (recipient == alice) numAliceWins++;
114112
}
115113
assertGt(numBobWins, 900);
116114
assertEq(numAliceWins, 0);
@@ -131,19 +129,6 @@ contract NftChanceBoosterHookTest is Test {
131129
}
132130
}
133131

134-
function testAfterClaimPrizeRedirectsPrize() public {
135-
address alice = holders[1];
136-
deal(address(prizePool.prizeToken()), address(nftBooster), 1e18);
137-
assertEq(prizePool.prizeToken().balanceOf(alice), 0);
138-
assertEq(prizePool.prizeToken().balanceOf(address(nftBooster)), 1e18);
139-
vm.expectEmit();
140-
emit PrizeWonByNftHolder(alice, address(this), address(1), 2, 3, 1e18);
141-
(bool success,) = address(nftBooster).call{ gas: 150_000 }(abi.encodeWithSelector(IPrizeHooks.afterClaimPrize.selector, address(1), 2, 3, 1e18, address(nftBooster), abi.encode(address(alice))));
142-
require(success, "afterClaimPrize failed");
143-
assertEq(prizePool.prizeToken().balanceOf(alice), 1e18);
144-
assertEq(prizePool.prizeToken().balanceOf(address(nftBooster)), 0);
145-
}
146-
147132
function testAfterClaimPrizeContributesPrize() public {
148133
deal(address(prizePool.prizeToken()), address(prizePool), 1e18 + prizePool.prizeToken().balanceOf(address(prizePool)));
149134
vm.expectEmit();

0 commit comments

Comments
 (0)