Skip to content

Commit

Permalink
Add minimum metadata calls to migration deployer
Browse files Browse the repository at this point in the history
  • Loading branch information
neokry committed Dec 27, 2023
1 parent e81cfce commit d08a3b9
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 17 deletions.
54 changes: 41 additions & 13 deletions src/deployers/L2MigrationDeployer.sol
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,20 @@ import { OPAddressAliasHelper } from "../lib/utils/OPAddressAliasHelper.sol";
/// @dev This contract is designed to be called from the OPStack L1CrossDomainMessenger or OptimismPortal
/// @author @neokry
contract L2MigrationDeployer {
/// ///
/// STRUCTS ///
/// ///

/// @notice The migration configuration for a deployment
/// @param tokenAddress The address of the deployed token
/// @param minimumMetadataCalls The minimum number of metadata calls expected to be made
/// @param executedMetadataCalls The number of metadata calls that have been executed
struct MigrationConfig {
address tokenAddress;
uint256 minimumMetadataCalls;
uint256 executedMetadataCalls;
}

/// ///
/// EVENTS ///
/// ///
Expand Down Expand Up @@ -44,6 +58,9 @@ contract L2MigrationDeployer {
/// @dev Metadata call failed
error METADATA_CALL_FAILED();

/// @dev Metadata calls not executed
error METADATA_CALLS_NOT_EXECUTED();

/// ///
/// IMMUTABLES ///
/// ///
Expand All @@ -61,8 +78,8 @@ contract L2MigrationDeployer {
/// STORAGE ///
/// ///

/// @notice Mapping of L1 deployer => L2 deployed token
mapping(address => address) public crossDomainDeployerToToken;
/// @notice Mapping of L1 deployer => L2 migration config
mapping(address => MigrationConfig) public crossDomainDeployerToMigration;

/// ///
/// CONSTRUCTOR ///
Expand Down Expand Up @@ -94,7 +111,8 @@ contract L2MigrationDeployer {
IManager.TokenParams calldata _tokenParams,
IManager.AuctionParams calldata _auctionParams,
IManager.GovParams calldata _govParams,
MerkleReserveMinter.MerkleMinterSettings calldata _minterParams
MerkleReserveMinter.MerkleMinterSettings calldata _minterParams,
uint256 _minimumMetadataCalls
) external returns (address token) {
if (_getTokenFromSender() != address(0)) {
revert DAO_ALREADY_DEPLOYED();
Expand All @@ -113,8 +131,8 @@ contract L2MigrationDeployer {
// Initilize minter with given params
MerkleReserveMinter(merkleMinter).setMintSettings(_token, _minterParams);

// Set the deployer
address deployer = _setTokenDeployer(_token);
// Set the migration config
address deployer = _setMigrationConfig(_token, _minimumMetadataCalls);

// Emit deployer set event
emit DeployerSet(_token, deployer);
Expand All @@ -124,7 +142,7 @@ contract L2MigrationDeployer {

///@notice Resets the stored deployment if L1 DAO wants to redeploy
function resetDeployment() external {
_resetTokenDeployer();
_resetMigrationConfig();
}

/// ///
Expand All @@ -142,6 +160,9 @@ contract L2MigrationDeployer {
function callMetadataRenderer(bytes memory _data) external {
(, address metadata, , , ) = _getDAOAddressesFromSender();

// Increment the number of metadata calls
crossDomainDeployerToMigration[_xMsgSender()].executedMetadataCalls++;

// Call the metadata renderer
(bool success, ) = metadata.call(_data);

Expand All @@ -168,6 +189,13 @@ contract L2MigrationDeployer {
function renounceOwnership() external {
(address token, , address auction, address treasury, ) = _getDAOAddressesFromSender();

MigrationConfig storage migration = crossDomainDeployerToMigration[_xMsgSender()];

// Revert if the minimum amount of metadata calls have not been executed
if (migration.executedMetadataCalls < migration.minimumMetadataCalls) {
revert METADATA_CALLS_NOT_EXECUTED();
}

// Transfer ownership of token contract
Ownable(token).transferOwnership(treasury);

Expand All @@ -190,22 +218,22 @@ contract L2MigrationDeployer {
: OPAddressAliasHelper.undoL1ToL2Alias(msg.sender);
}

function _setTokenDeployer(address token) private returns (address deployer) {
function _setMigrationConfig(address token, uint256 minimumMetadataCalls) private returns (address deployer) {
deployer = _xMsgSender();

// Set the deployer state so the xDomain caller can easily access in future calls
// Also prevents accidental re-deployment
crossDomainDeployerToToken[deployer] = token;
crossDomainDeployerToMigration[deployer].tokenAddress = token;
crossDomainDeployerToMigration[deployer].minimumMetadataCalls = minimumMetadataCalls;
crossDomainDeployerToMigration[deployer].executedMetadataCalls = 0;
}

function _resetTokenDeployer() private {
function _resetMigrationConfig() private {
// Reset the deployer state so the xDomain caller can redeploy
delete crossDomainDeployerToToken[_xMsgSender()];
delete crossDomainDeployerToMigration[_xMsgSender()];
}

function _getTokenFromSender() private view returns (address) {
// Return the token address if it has been deployed by the xDomain caller
return crossDomainDeployerToToken[_xMsgSender()];
return crossDomainDeployerToMigration[_xMsgSender()].tokenAddress;
}

function _getDAOAddressesFromSender()
Expand Down
50 changes: 46 additions & 4 deletions test/L2MigrationDeployer.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ contract L2MigrationDeployerTest is NounsBuilderTest {

vm.startPrank(address(xDomainMessenger));

address _token = deployer.deploy(foundersArr, tokenParams, auctionParams, govParams, minterParams);
address _token = deployer.deploy(foundersArr, tokenParams, auctionParams, govParams, minterParams, 1);

addMetadataProperties();

Expand All @@ -61,6 +61,36 @@ contract L2MigrationDeployerTest is NounsBuilderTest {
vm.label(address(governor), "GOVERNOR");
}

function deployAlt() internal {
setAltMockFounderParams();

setMockTokenParams();

setMockAuctionParams();

setMockGovParams();

vm.startPrank(address(xDomainMessenger));

address _token = deployer.deploy(foundersArr, tokenParams, auctionParams, govParams, minterParams, 1);

vm.stopPrank();

(address _metadata, address _auction, address _treasury, address _governor) = manager.getAddresses(_token);

token = Token(_token);
metadataRenderer = MetadataRenderer(_metadata);
auction = Auction(_auction);
treasury = Treasury(payable(_treasury));
governor = Governor(_governor);

vm.label(address(token), "TOKEN");
vm.label(address(metadataRenderer), "METADATA_RENDERER");
vm.label(address(auction), "AUCTION");
vm.label(address(treasury), "TREASURY");
vm.label(address(governor), "GOVERNOR");
}

function setAltMockFounderParams() internal virtual {
address[] memory wallets = new address[](3);
uint256[] memory percents = new uint256[](3);
Expand Down Expand Up @@ -107,6 +137,14 @@ contract L2MigrationDeployerTest is NounsBuilderTest {
deploy();
}

function testRevert_DeployNoMetadata() external {
deployAlt();

vm.prank(address(xDomainMessenger));
vm.expectRevert(abi.encodeWithSignature("METADATA_CALLS_NOT_EXECUTED()"));
deployer.renounceOwnership();
}

function test_MinterIsSet() external {
deploy();

Expand Down Expand Up @@ -148,12 +186,16 @@ contract L2MigrationDeployerTest is NounsBuilderTest {
function test_ResetDeployment() external {
deploy();

assertEq(deployer.crossDomainDeployerToToken(xDomainMessenger.xDomainMessageSender()), address(token));
(address token, , ) = deployer.crossDomainDeployerToMigration(xDomainMessenger.xDomainMessageSender());

assertEq(token, address(token));

vm.prank(address(xDomainMessenger));
deployer.resetDeployment();

assertEq(deployer.crossDomainDeployerToToken(xDomainMessenger.xDomainMessageSender()), address(0));
(address newToken, , ) = deployer.crossDomainDeployerToMigration(xDomainMessenger.xDomainMessageSender());

assertEq(newToken, address(0));
}

function test_DepositToTreasury() external {
Expand Down Expand Up @@ -184,6 +226,6 @@ contract L2MigrationDeployerTest is NounsBuilderTest {

vm.prank(address(xDomainMessenger));
vm.expectRevert(abi.encodeWithSignature("DAO_ALREADY_DEPLOYED()"));
deployer.deploy(foundersArr, tokenParams, auctionParams, govParams, minterParams);
deployer.deploy(foundersArr, tokenParams, auctionParams, govParams, minterParams, 1);
}
}

0 comments on commit d08a3b9

Please sign in to comment.