-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(script): implement
add-v0.3.4-rns-unified-migration-script
(#185)
- Loading branch information
Showing
11 changed files
with
513 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,4 +20,5 @@ docs/ | |
node_modules/ | ||
yarn-error.log | ||
.yarn | ||
.yarnrc.yml | ||
.yarnrc.yml | ||
script/data/* |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Submodule forge-std
updated
17 files
+1 −0 | .gitattributes | |
+1 −1 | package.json | |
+635 −0 | scripts/vm.py | |
+16 −4 | src/StdChains.sol | |
+2 −2 | src/StdCheats.sol | |
+5 −1 | src/StdJson.sol | |
+61 −33 | src/StdUtils.sol | |
+958 −418 | src/Vm.sol | |
+216 −0 | src/mocks/MockERC20.sol | |
+221 −0 | src/mocks/MockERC721.sol | |
+2 −6 | test/StdChains.t.sol | |
+1 −1 | test/StdCheats.t.sol | |
+3 −1 | test/StdError.t.sol | |
+2 −2 | test/StdUtils.t.sol | |
+15 −0 | test/Vm.t.sol | |
+441 −0 | test/mocks/MockERC20.t.sol | |
+721 −0 | test/mocks/MockERC721.t.sol |
Submodule foundry-deployment-kit
updated
20 files
+10 −2 | broadcast.sh | |
+0 −1 | debug.sh | |
+1 −1 | lib/forge-std | |
+21 −4 | run.sh | |
+15 −6 | script/ArtifactFactory.sol | |
+8 −0 | script/BaseGeneralConfig.sol | |
+97 −21 | script/BaseMigration.s.sol | |
+1 −3 | script/configs/ContractConfig.sol | |
+5 −1 | script/configs/MigrationConfig.sol | |
+5 −1 | script/configs/NetworkConfig.sol | |
+11 −1 | script/configs/RuntimeConfig.sol | |
+19 −21 | script/configs/WalletConfig.sol | |
+22 −6 | script/extensions/ScriptExtended.s.sol | |
+2 −0 | script/interfaces/configs/IMigrationConfig.sol | |
+2 −0 | script/interfaces/configs/INetworkConfig.sol | |
+6 −1 | script/interfaces/configs/IRuntimeConfig.sol | |
+4 −0 | script/interfaces/configs/IWalletConfig.sol | |
+4 −4 | script/libraries/LibProxy.sol | |
+3 −1 | script/utils/DefaultContract.sol | |
+21 −0 | src/Proxy.sol |
94 changes: 94 additions & 0 deletions
94
...parate-tier-and-domain-price/01_UpgradeRNSDomainPrice_OverrideTierForCommunityNames.s.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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))); | ||
} | ||
} | ||
} |
48 changes: 48 additions & 0 deletions
48
...0215-separate-tier-and-domain-price/02_ResetCommunityNameRenewalFees_RNSDomainPrice.s.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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]); | ||
} | ||
} | ||
} |
148 changes: 148 additions & 0 deletions
148
script/20240215-separate-tier-and-domain-price/03_DeployNewRNSOperation_RNSOperation.s.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
} | ||
} |
55 changes: 55 additions & 0 deletions
55
script/20240215-separate-tier-and-domain-price/20240215_Migration.s.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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()); | ||
} | ||
} | ||
} |
Oops, something went wrong.