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

feat(nfts): tbz s2 recruitments contract upgrade #18556

Merged
merged 19 commits into from
Jan 22, 2025
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
6178142
tbz updated blacklist
bearni95 Oct 10, 2024
439b237
Merge branch 'main' of ssh://github.com/taikoxyz/taiko-mono
bearni95 Oct 11, 2024
f50eeb6
Merge branch 'main' of ssh://github.com/taikoxyz/taiko-mono
bearni95 Oct 16, 2024
cb0e4a8
Merge branch 'main' of ssh://github.com/taikoxyz/taiko-mono
bearni95 Oct 17, 2024
999f49e
Merge branch 'main' of ssh://github.com/taikoxyz/taiko-mono
bearni95 Dec 2, 2024
94c69a7
Merge branch 'main' of ssh://github.com/taikoxyz/taiko-mono
bearni95 Dec 3, 2024
5a6f431
Merge branch 'main' of ssh://github.com/taikoxyz/taiko-mono
bearni95 Dec 6, 2024
a35c6a7
added claim hash check on recruitmentV2 to prevent double-using the s…
bearni95 Dec 6, 2024
05cf898
added deployment/upgrade script
bearni95 Dec 6, 2024
0bdd071
added comments
bearni95 Dec 6, 2024
e86cccc
Merge branch 'main' of ssh://github.com/taikoxyz/taiko-mono
bearni95 Dec 9, 2024
ed4d78e
Merge branch 'main' of ssh://github.com/taikoxyz/taiko-mono
bearni95 Dec 16, 2024
4739884
Merge branch 'main' of ssh://github.com/taikoxyz/taiko-mono
bearni95 Dec 16, 2024
d5166cc
Merge branch 'main' of ssh://github.com/taikoxyz/taiko-mono
bearni95 Jan 9, 2025
965d42b
Merge branch 'main' of ssh://github.com/taikoxyz/taiko-mono
bearni95 Jan 22, 2025
20cabbe
Merge branch 'main' into tbz-s2-badges-free-claim-hash-registry
bearni95 Jan 22, 2025
93a45f2
restored unwanted changes
bearni95 Jan 22, 2025
795e0f5
revert unwanted protocol changes
bearni95 Jan 22, 2025
ae835cd
revert unwanted protocol changes
bearni95 Jan 22, 2025
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
122 changes: 122 additions & 0 deletions packages/nfts/contracts/trailblazers-season-2/BadgeRecruitmentV2.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.24;

import "../trailblazers-badges/TrailblazersBadgesV3.sol";
import "./BadgeRecruitment.sol";

contract BadgeRecruitmentV2 is BadgeRecruitment {
/// @notice Error
error HASH_ALREADY_CLAIMED();
/// @notice Registry for used hashes

mapping(bytes32 _hash => bool _isUsed) public usedClaimHashes;
/// @notice Version of the contract
/// @return The version of the contract

function version() external view virtual returns (string memory) {
return "v2";
}
/// @notice Start a recruitment for a badge using the user's experience points
/// @param _hash The hash to sign of the signature
/// @param _v The signature V field
/// @param _r The signature R field
/// @param _s The signature S field
/// @param _exp The user's experience points

function startRecruitment(
bytes32 _hash,
uint8 _v,
bytes32 _r,
bytes32 _s,
uint256 _exp
)
external
virtual
override
isNotMigrating(_msgSender())
{
bytes32 calculatedHash_ = generateClaimHash(HashType.Start, _msgSender(), _exp);

if (calculatedHash_ != _hash) {
revert HASH_MISMATCH();
}

if (usedClaimHashes[_hash]) {
revert HASH_ALREADY_CLAIMED();
}

(address recovered_,,) = ECDSA.tryRecover(_hash, _v, _r, _s);
if (recovered_ != randomSigner) {
revert NOT_RANDOM_SIGNER();
}

if (_exp < userExperience[_msgSender()]) {
revert EXP_TOO_LOW();
}

userExperience[_msgSender()] = _exp;

RecruitmentCycle memory cycle_ = recruitmentCycles[recruitmentCycleId];
if (cycle_.startTime > block.timestamp || cycle_.endTime < block.timestamp) {
revert RECRUITMENT_NOT_ENABLED();
}
uint256 randomSeed_ = randomFromSignature(_hash, _v, _r, _s);
uint256 s1BadgeId_ = cycle_.s1BadgeIds[randomSeed_ % cycle_.s1BadgeIds.length];

if (
recruitmentCycleUniqueMints[recruitmentCycleId][_msgSender()][s1BadgeId_][RecruitmentType
.Claim]
) {
revert ALREADY_MIGRATED_IN_CYCLE();
}

_startRecruitment(_msgSender(), s1BadgeId_, 0, RecruitmentType.Claim);
usedClaimHashes[_hash] = true;
}

/// @notice Start a recruitment for a badge using the user's experience points
/// @param _hash The hash to sign of the signature
/// @param _v The signature V field
/// @param _r The signature R field
/// @param _s The signature S field
/// @param _exp The user's experience points
/// @param _s1BadgeId The badge ID (s1)
function startRecruitment(
bytes32 _hash,
uint8 _v,
bytes32 _r,
bytes32 _s,
uint256 _exp,
uint256 _s1BadgeId
)
external
virtual
override
isNotMigrating(_msgSender())
recruitmentOpen(_s1BadgeId)
hasntMigratedInCycle(_s1BadgeId, _msgSender(), RecruitmentType.Claim)
{
bytes32 calculatedHash_ = generateClaimHash(HashType.Start, _msgSender(), _s1BadgeId);

if (calculatedHash_ != _hash) {
revert HASH_MISMATCH();
}

if (usedClaimHashes[_hash]) {
revert HASH_ALREADY_CLAIMED();
}

(address recovered_,,) = ECDSA.tryRecover(_hash, _v, _r, _s);
if (recovered_ != randomSigner) {
revert NOT_RANDOM_SIGNER();
}

if (_exp < userExperience[_msgSender()]) {
revert EXP_TOO_LOW();
}

userExperience[_msgSender()] = _exp;
_startRecruitment(_msgSender(), _s1BadgeId, 0, RecruitmentType.Claim);
usedClaimHashes[calculatedHash_] = true;
}
}
6 changes: 3 additions & 3 deletions packages/nfts/deployments/trailblazers-season-2/hekla.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"BadgeRecruitment": "0xBd368C65Cb354eBAd6c1429b551bD0197f19C2B8",
"BadgeRecruitment": "0x0232BA6d2a398E32e7CCb88b3e1c927Cb52117EF",
"Owner": "0x4100a9B680B1Be1F10Cb8b5a57fE59eA77A8184e",
"TrailblazersBadges": "0x9E14C357E964BeE012bA82Ce9d6513dAec6ea961",
"TrailblazersBadgesS2": "0xc84B76a5836Cb0CeF094808af445F7E98504ED5B"
"TrailblazersBadges": "0xB2E2Ac2e1976144d6B2C3ECEa21F290e89Ca3edc",
"TrailblazersBadgesS2": "0xbcb2B103715F141c7535d346728840ac9AC0f174"
}
9 changes: 4 additions & 5 deletions packages/nfts/script/trailblazers-season-2/Deploy.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,12 @@ contract DeployS2Script is Script {
BadgeRecruitment recruitment;

// Taiko Mainnet Values
/*
//address owner = 0xf8ff2AF0DC1D5BA4811f22aCb02936A1529fd2Be;
address claimMintSigner = 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266;
address recruitmentSigner = 0x9Fc8d56c7376f9b062FEe7E02BAdFA670d603248;
string baseURI =
"https://taikonfts.4everland.link/ipfs/bafybeiatuzeeeznd3hi5qiulslxcjd22ebu45t4fra2jvi3smhocr2c66a";
"https://taikonfts.4everland.link/ipfs/bafybeiatuzeeeznd3hi5qiulslxcjd22ebu45t4fra2jvi3smhocr2c66a";
IMinimalBlacklist blacklist = IMinimalBlacklist(0xfA5EA6f9A13532cd64e805996a941F101CCaAc9a);
uint256 public MAX_INFLUENCES = 5;
Expand All @@ -37,11 +38,10 @@ contract DeployS2Script is Script {
uint256 public DEFAULT_CYCLE_DURATION = 7 days;
uint256 public s1EndDate = 1_734_350_400; // Dec 16th 2024, noon UTC
uint256 public S1_LOCK_DURATION = (s1EndDate - block.timestamp);

*/
// Hekla Testnet Values
/*
string baseURI =
"https://taikonfts.4everland.link/ipfs/bafybeiatuzeeeznd3hi5qiulslxcjd22ebu45t4fra2jvi3smhocr2c66a";
"https://taikonfts.4everland.link/ipfs/bafybeiatuzeeeznd3hi5qiulslxcjd22ebu45t4fra2jvi3smhocr2c66a";

IMinimalBlacklist blacklist = IMinimalBlacklist(0xe61E9034b5633977eC98E302b33e321e8140F105);
address claimMintSigner = 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266;
Expand All @@ -54,7 +54,6 @@ contract DeployS2Script is Script {
uint256 public MAX_INFLUENCES_DIVIDER = 100;
uint256 public DEFAULT_CYCLE_DURATION = 7 days;
uint256 public S1_LOCK_DURATION = 365 days;
*/

address s1Contract = 0xa20a8856e00F5ad024a55A663F06DCc419FFc4d5;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.24;

import { UtilsScript } from "./Utils.s.sol";
import { Script, console } from "forge-std/src/Script.sol";
import { BadgeRecruitment } from "../../contracts/trailblazers-season-2/BadgeRecruitment.sol";
import { BadgeRecruitmentV2 } from "../../contracts/trailblazers-season-2/BadgeRecruitmentV2.sol";

contract UpgradeRecruitmentsV2 is Script {
UtilsScript public utils;
string public jsonLocation;
uint256 public deployerPrivateKey;

address recruitmentAddress = 0xa9Ceb04F3aF71fF123409d426A92BABb5124970C;
BadgeRecruitment public recruitmentV1;
BadgeRecruitmentV2 public recruitmentV2;

function setUp() public {
utils = new UtilsScript();
utils.setUp();

jsonLocation = utils.getContractJsonLocation();
deployerPrivateKey = utils.getPrivateKey();
}

function run() public {
vm.startBroadcast(deployerPrivateKey);
recruitmentV1 = BadgeRecruitment(recruitmentAddress);

recruitmentV1.upgradeToAndCall(
address(new BadgeRecruitmentV2()), abi.encodeCall(BadgeRecruitmentV2.version, ())
);

recruitmentV2 = BadgeRecruitmentV2(address(recruitmentV1));

console.log("Upgraded BadgeRecruitmentV2 to:", address(recruitmentV2));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { TrailblazersBadgesV4 } from
"../../contracts/trailblazers-season-2/TrailblazersS1BadgesV4.sol";
import { BadgeRecruitment } from "../../contracts/trailblazers-season-2/BadgeRecruitment.sol";

contract TrailblazersBadgesS2Test is Test {
contract BadgeRecruitmentTest is Test {
UtilsScript public utils;

TrailblazersBadgesV4 public s1BadgesV4;
Expand Down
Loading
Loading