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(script): implement add-v0.3.4-rns-unified-migration-script #185

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
903c0d7
forge install: foundry-deployment-kit
TuDo1403 Dec 18, 2023
76e962b
forge install: contract-libs
TuDo1403 Dec 18, 2023
1453169
feat: migrate all migrations script to new foundry-deployment-kit ver…
TuDo1403 Dec 18, 2023
35646fe
chore: update foundry-deployment-kit
TuDo1403 Feb 11, 2024
9ca988a
script: move validate logic into post check function, reuse script lo…
TuDo1403 Feb 11, 2024
a681418
script: split parameters in ISharedArgument
TuDo1403 Feb 11, 2024
c41d583
script: minor refactor
TuDo1403 Feb 11, 2024
e17a8ed
chore: update forge-std
TuDo1403 Feb 11, 2024
962a73e
forge install: foundry-deployment-kit
TuDo1403 Feb 11, 2024
b101363
script: add migration script for v0.3.4
TuDo1403 Feb 18, 2024
0676eda
forge install: foundry-deployment-kit
TuDo1403 Feb 20, 2024
d28e57b
forge install: foundry-deployment-kit
TuDo1403 Feb 20, 2024
8fbbecc
script: minor fix script
TuDo1403 Feb 20, 2024
b87cf5c
script: minor fix script
TuDo1403 Feb 20, 2024
7ec1084
script: minor script fix and add rns operation deploy script
TuDo1403 Feb 21, 2024
138e7a0
script: resolve conflict
TuDo1403 Feb 23, 2024
399a1ef
Merge branch 'feature/tier' into implement-feature/script/add-v0.3.4-…
TuDo1403 Mar 12, 2024
8fe81bb
script: add bash script for bulk override tiers and bulk reset renewa…
TuDo1403 Mar 12, 2024
112ebf2
forge install: foundry-deployment-kit
TuDo1403 Mar 12, 2024
2a13fb9
chore: rename script
TuDo1403 Mar 12, 2024
cfc362d
script: move override tier to post check
TuDo1403 Mar 13, 2024
1f23eb8
Merge branch 'feature/script' into implement-feature/script/add-v0.3.…
TuDo1403 Mar 25, 2024
a374601
fix: resolve conflict
TuDo1403 Mar 25, 2024
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
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,5 @@ docs/
node_modules/
yarn-error.log
.yarn
.yarnrc.yml
.yarnrc.yml
script/data/*
8 changes: 5 additions & 3 deletions config.sh
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ loadConfig() {
ERC721_BATCH_TRANSFER=0x2368dfed532842db89b470fde9fd584d48d4f644

if [ "$MODE" == "broadcast" ]; then
PK=$TESTNET_PK
PK=$MAINNET_PK
fi
else
RPC=$TESTNET_URL
Expand All @@ -37,18 +37,20 @@ loadConfig() {
ERC721_BATCH_TRANSFER=0x2e889348bd37f192063bfec8ff39bd3635949e20

if [ "$MODE" == "broadcast" ]; then
PK=$MAINNET_PK
PK=$TESTNET_PK
fi
fi

if [ "$MODE" == "broadcast" ]; then
CURRENT_NONCE=$(cast nonce --rpc-url $RPC $FROM)
CURRENT_GAS_PRICE=$(cast gas-price --rpc-url $RPC)

if [[ "$PK" == op://* ]]; then
PK=$(op read "$PK")
fi
fi

CURRENT_NONCE=$(cast nonce --rpc-url $RPC $FROM)
echo "Current nonce: $CURRENT_NONCE"
}

# Function to load address from deployment file
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import { StdStyle } from "forge-std/StdStyle.sol";
import { IMulticall3 } from "forge-std/interfaces/IMulticall3.sol";
import { LibString } from "solady/utils/LibString.sol";
import { DefaultNetwork } from "foundry-deployment-kit/utils/DefaultNetwork.sol";
import { DefaultContract } from "foundry-deployment-kit/utils/DefaultContract.sol";
import { Contract } from "../utils/Contract.sol";
import { INSDomainPrice, RNSDomainPrice } from "@rns-contracts/RNSDomainPrice.sol";
import "./20240215_Migration.s.sol";

contract Migration__01_UpgradeRNSDomainPriceAndOverrideTierForCommunityNames_RNSDomainPrice is Migration__20240215 {
using StdStyle for *;
using LibString for *;

RNSDomainPrice internal _domainPrice;
IMulticall3 internal _multicall;
bytes32[] internal _lbHashes;

function run() external {
_domainPrice = RNSDomainPrice(_upgradeProxy(Contract.RNSDomainPrice.key()));
}

function _postCheck() internal override logFn("_postChecking ...") {
_multicall = IMulticall3(loadContract(DefaultContract.Multicall3.key()));

(_labels, _tiers) = _parseData(DATA_PATH);

_lbHashes = toLabelHashes(_labels);

uint256 batchSize = 100;
uint256 totalElements = _lbHashes.length;
uint256 totalBatches = (totalElements + batchSize - 1) / batchSize;

address overrider = _domainPrice.getRoleMember(_domainPrice.OVERRIDER_ROLE(), 0);
console.log("Overrider".yellow(), overrider);

for (uint256 i; i < totalBatches; i++) {
console.log("Processing batch", i, "of", totalBatches);
uint256 start = i * batchSize;
uint256 end = (i + 1) * batchSize;
if (end > totalElements) end = totalElements;

bytes32[] memory batchHashes = new bytes32[](end - start);
INSDomainPrice.Tier[] memory batchTiers = new INSDomainPrice.Tier[](end - start);

for (uint256 j = start; j < end; j++) {
batchHashes[j - start] = _lbHashes[j];
batchTiers[j - start] = _tiers[j];
}

vm.prank(overrider);
_domainPrice.bulkOverrideTiers(batchHashes, batchTiers);
}

_validateOverridenTiers();
_validateOtherDomainTiers();
}

function _validateOtherDomainTiers() internal logFn("_validating other domain tiers ...") {
if (network() == DefaultNetwork.RoninMainnet.key()) {
assertEq(uint8(_domainPrice.getTier("tudo")), uint8(INSDomainPrice.Tier.Tier2), "invalid tier for tudo");
assertEq(uint8(_domainPrice.getTier("duke")), uint8(INSDomainPrice.Tier.Tier2), "invalid tier for duke");
assertEq(uint8(_domainPrice.getTier("ace")), uint8(INSDomainPrice.Tier.Tier1), "invalid tier for ace");
assertEq(uint8(_domainPrice.getTier("dragon")), uint8(INSDomainPrice.Tier.Tier2), "invalid tier for dragon");
assertEq(uint8(_domainPrice.getTier("tokuda")), uint8(INSDomainPrice.Tier.Tier3), "invalid tier for tokuda");
assertEq(uint8(_domainPrice.getTier("metaverse")), uint8(INSDomainPrice.Tier.Tier2), "invalid tier for metaverse");
assertEq(uint8(_domainPrice.getTier("nuke")), uint8(INSDomainPrice.Tier.Tier2), "invalid tier for nuke");
assertEq(
uint8(_domainPrice.getTier("merchandising")), uint8(INSDomainPrice.Tier.Tier3), "invalid tier for merchandising"
);
}
}

function _validateOverridenTiers() internal logFn("_validating overriden tiers ...") {
IMulticall3.Call[] memory calls = new IMulticall3.Call[](_lbHashes.length);

for (uint256 i; i < _lbHashes.length; ++i) {
calls[i] = IMulticall3.Call({
target: address(_domainPrice),
callData: abi.encodeCall(_domainPrice.getTier, (_labels[i]))
});
}

(, bytes[] memory returnData) = _multicall.aggregate(calls);
INSDomainPrice.Tier[] memory tiers = new INSDomainPrice.Tier[](_lbHashes.length);

for (uint256 i; i < _lbHashes.length; ++i) {
tiers[i] = abi.decode(returnData[i], (INSDomainPrice.Tier));
assertEq(uint8(tiers[i]), uint8(_tiers[i]), string.concat("tier not set", vm.toString(i)));
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import { INSDomainPrice, RNSDomainPrice } from "@rns-contracts/RNSDomainPrice.sol";
import { Contract } from "../utils/Contract.sol";
import "./20240215_Migration.s.sol";

contract Migration__02_ResetCommunityNamesRenewalFees_RNSDomainPrice is Migration__20240215 {
bytes32[] internal _lbHashes;

function run() external {
RNSDomainPrice rnsDomainPrice = RNSDomainPrice(loadContract(Contract.RNSDomainPrice.key()));

_lbHashes = toLabelHashes(_labels);

address overrider = rnsDomainPrice.getRoleMember(rnsDomainPrice.OVERRIDER_ROLE(), 0);
uint256 batchSize = 100;
uint256 totalBatches = (_lbHashes.length + batchSize - 1) / batchSize;

for (uint256 batchIndex = 0; batchIndex < totalBatches; batchIndex++) {
uint256 startIndex = batchIndex * batchSize;
uint256 endIndex = startIndex + batchSize;
if (endIndex > _lbHashes.length) {
endIndex = _lbHashes.length;
}

bytes32[] memory batchLbHashes = new bytes32[](endIndex - startIndex);
uint256[] memory batchRenewalFees = new uint256[](endIndex - startIndex);

for (uint256 i = startIndex; i < endIndex; i++) {
batchLbHashes[i - startIndex] = _lbHashes[i];
batchRenewalFees[i - startIndex] = type(uint256).max;
}

vm.broadcast(overrider);
rnsDomainPrice.bulkOverrideRenewalFees(batchLbHashes, batchRenewalFees);
}
}

function _postCheck() internal override logFn("_postChecking ...") {
RNSDomainPrice rnsDomainPrice = RNSDomainPrice(loadContract(Contract.RNSDomainPrice.key()));

for (uint256 i; i < _lbHashes.length; ++i) {
vm.expectRevert(INSDomainPrice.RenewalFeeIsNotOverriden.selector);
rnsDomainPrice.getOverriddenRenewalFee(_labels[i]);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import { StdStyle } from "forge-std/StdStyle.sol";
import { Math } from "@openzeppelin/contracts/utils/math/Math.sol";
import { console2 as console } from "forge-std/console2.sol";
import { Contract } from "script/utils/Contract.sol";
import { Migration } from "script/Migration.s.sol";
import { RNSUnified } from "@rns-contracts/RNSUnified.sol";
import { INSDomainPrice, RNSDomainPrice } from "@rns-contracts/RNSDomainPrice.sol";
import { INSAuction, RNSAuction } from "@rns-contracts/RNSAuction.sol";
import { LibRNSDomain } from "@rns-contracts/libraries/LibRNSDomain.sol";
import { RNSOperation, RNSOperationDeploy } from "script/contracts/RNSOperationDeploy.s.sol";

contract Migration_03_DeployNewRNSOperation_RNSOperation is Migration {
using LibRNSDomain for string;
using StdStyle for *;

RNSUnified private rns;
RNSAuction private auction;
RNSOperation private rnsOperation;
RNSDomainPrice private domainPrice;

function run() public {
rnsOperation = new RNSOperationDeploy().run();

domainPrice = RNSDomainPrice(loadContract(Contract.RNSDomainPrice.key()));
rns = RNSUnified(loadContract(Contract.RNSUnified.key()));
auction = RNSAuction(loadContract(Contract.RNSAuction.key()));

address admin = rns.ownerOf(LibRNSDomain.RON_ID);
console.log("admin".yellow(), admin);

vm.broadcast(rnsOperation.owner());
rnsOperation.transferOwnership(admin);

vm.startBroadcast(admin);

rns.setApprovalForAll(address(rnsOperation), true);
auction.grantRole(auction.OPERATOR_ROLE(), address(rnsOperation));
rns.grantRole(rns.PROTECTED_SETTLER_ROLE(), address(rnsOperation));
domainPrice.grantRole(domainPrice.OVERRIDER_ROLE(), address(rnsOperation));

vm.stopBroadcast();
}

function _postCheck() internal override {
_validateBulkMint();
_validateOverridenTiers();
_validateBulkSetProtected();
_validateBulkOverrideRenewalFees();
_validateReclaimAuctionNames({ searchSize: 20 });
}

function _validateOverridenTiers() internal logFn("_validateOverridenTiers") {
string[] memory labels = new string[](5);
labels[0] = "heidi";
labels[1] = "luke";
labels[2] = "sophia";
labels[3] = "chief";
labels[4] = "slim";

for (uint256 i; i < labels.length; ++i) {
assertEq(
uint8(domainPrice.getTier(labels[i])),
uint8(INSDomainPrice.Tier.Tier1),
string.concat("invalid tier for auction label ", labels[i])
);
}
}

function _validateBulkOverrideRenewalFees() internal logFn("_validateBulkOverrideRenewalFees") {
string memory label = "tudo-provip-maximum-ultra";
string[] memory labels = new string[](1);
labels[0] = label;
uint256[] memory yearlyUSDPrices = new uint256[](1);
// 10 usd per year
yearlyUSDPrices[0] = 10;

vm.prank(rnsOperation.owner());
rnsOperation.bulkOverrideRenewalFees(labels, yearlyUSDPrices);

assertEq(domainPrice.getOverriddenRenewalFee(label), Math.mulDiv(yearlyUSDPrices[0], 1 ether, 365 days));
}

function _validateReclaimAuctionNames(uint256 searchSize) internal logFn("_validateReclaimAuctionNames") {
INSAuction.DomainAuction[] memory domainAuctions = new INSAuction.DomainAuction[](searchSize);
uint256[] memory reservedIds = new uint256[](searchSize);
for (uint256 i; i < searchSize; ++i) {
reservedIds[i] = rns.tokenOfOwnerByIndex(address(auction), i);
(domainAuctions[i],) = auction.getAuction(reservedIds[i]);
}

uint256 reclaimableAuctionNameId;
for (uint256 i; i < searchSize; ++i) {
if (domainAuctions[i].bid.bidder == address(0x0)) {
reclaimableAuctionNameId = reservedIds[i];
break;
}
}

address to = makeAddr("to");
address[] memory tos = new address[](1);
tos[0] = to;
string memory label = rns.getRecord(reclaimableAuctionNameId).immut.label;
console.log("reclaimable auction label", label);
string[] memory labels = new string[](1);
labels[0] = label;

vm.prank(rnsOperation.owner());
rnsOperation.reclaimUnbiddedNames({ tos: tos, labels: labels, allowFailure: false });
}

function _validateBulkMint() internal logFn("_validateBulkMint") {
address to = makeAddr("to");
address[] memory tos = new address[](1);
tos[0] = to;
string[] memory labels = new string[](1);
labels[0] = "tudo-provip-maximum-utra";
uint64 duration = uint64(3 days);

vm.prank(rnsOperation.owner());
rnsOperation.bulkMint(tos, labels, duration);

uint256 id = uint256(string.concat(labels[0], ".ron").namehash());
assertEq(rns.ownerOf(id), to);
}

function _validateBulkSetProtected() internal logFn("_validateBulkSetProtected") {
string[] memory labels = new string[](1);
labels[0] = "tudo-provip-maximum-utra";

bool shouldProtect = true;

vm.prank(rnsOperation.owner());
rnsOperation.bulkSetProtected(labels, shouldProtect);

uint256 id = uint256(string.concat(labels[0], ".ron").namehash());
assertTrue(rns.getRecord(id).mut.protected);

shouldProtect = false;

vm.prank(rnsOperation.owner());
rnsOperation.bulkSetProtected(labels, shouldProtect);

assertFalse(rns.getRecord(id).mut.protected);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import { console2 as console } from "forge-std/console2.sol";
import { JSONParserLib } from "solady/utils/JSONParserLib.sol";
import { Migration, ISharedArgument } from "../Migration.s.sol";
import { LibRNSDomain } from "@rns-contracts/libraries/LibRNSDomain.sol";
import { INSDomainPrice } from "@rns-contracts/interfaces/INSDomainPrice.sol";

contract Migration__20240215 is Migration {
using JSONParserLib for *;
using LibRNSDomain for *;

string internal constant DATA_PATH = "script/data/517 Community names (Tier 1) - _3 characters.json";

INSDomainPrice.Tier[] internal _tiers;
string[] internal _labels;

constructor() { }

function toLabelHashes(string[] memory labels) internal pure returns (bytes32[] memory) {
bytes32[] memory hashes = new bytes32[](labels.length);
for (uint256 i; i < labels.length; ++i) {
hashes[i] = labels[i].hashLabel();
}
return hashes;
}

function toNameHashes(string[] memory labels) internal pure returns (uint256[] memory) {
uint256[] memory hashes = new uint256[](labels.length);
for (uint256 i; i < labels.length; ++i) {
hashes[i] = uint256(labels[i].namehash());
}
return hashes;
}

function _parseData(string memory path)
internal
view
returns (string[] memory labels, INSDomainPrice.Tier[] memory tiers)
{
string memory raw = vm.readFile(path);
JSONParserLib.Item memory communityNames = raw.parse().at('"communityNames"');
uint256 length = communityNames.size();
console.log("length", length);

labels = new string[](length);
tiers = new INSDomainPrice.Tier[](length);

for (uint256 i; i < length; ++i) {
tiers[i] = INSDomainPrice.Tier(uint8(vm.parseUint(communityNames.at(i).at('"tier"').value().decodeString())));
labels[i] = (communityNames.at(i).at('"domain"').value().decodeString());
}
}
}
Loading
Loading