generated from m0-foundation/foundry-template
-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
55896c2
commit 5c1e17d
Showing
6 changed files
with
183 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
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,57 @@ | ||
// SPDX-License-Identifier: UNLICENSED | ||
|
||
pragma solidity 0.8.23; | ||
|
||
import { ContractHelper } from "../lib/common/src/libs/ContractHelper.sol"; | ||
|
||
import { WrappedMToken } from "../src/WrappedMToken.sol"; | ||
import { Proxy } from "../src/Proxy.sol"; | ||
|
||
contract DeployBase { | ||
/** | ||
* @dev Deploys Wrapped M Token. | ||
* @param mToken_ The address the M Token contract. | ||
* @param migrationAdmin_ The address the Migration Admin. | ||
* @return implementation_ The address of the deployed Wrapped M Token implementation. | ||
* @return proxy_ The address of the deployed Wrapped M Token proxy. | ||
*/ | ||
function deploy( | ||
address mToken_, | ||
address migrationAdmin_ | ||
) public virtual returns (address implementation_, address proxy_) { | ||
// Wrapped M token needs `mToken_` and `migrationAdmin_` addresses. | ||
// Proxy needs `implementation_` addresses. | ||
|
||
implementation_ = address(new WrappedMToken(mToken_, migrationAdmin_)); | ||
proxy_ = address(new Proxy(implementation_)); | ||
} | ||
|
||
function _getExpectedWrappedMTokenImplementation( | ||
address deployer_, | ||
uint256 deployerNonce_ | ||
) internal pure returns (address) { | ||
return ContractHelper.getContractFrom(deployer_, deployerNonce_); | ||
} | ||
|
||
function getExpectedWrappedMTokenImplementation( | ||
address deployer_, | ||
uint256 deployerNonce_ | ||
) public pure virtual returns (address) { | ||
return _getExpectedWrappedMTokenImplementation(deployer_, deployerNonce_); | ||
} | ||
|
||
function _getExpectedWrappedMTokenProxy(address deployer_, uint256 deployerNonce_) internal pure returns (address) { | ||
return ContractHelper.getContractFrom(deployer_, deployerNonce_ + 1); | ||
} | ||
|
||
function getExpectedWrappedMTokenProxy( | ||
address deployer_, | ||
uint256 deployerNonce_ | ||
) public pure virtual returns (address) { | ||
return _getExpectedWrappedMTokenProxy(deployer_, deployerNonce_); | ||
} | ||
|
||
function getDeployerNonceAfterProtocolDeployment(uint256 deployerNonce_) public pure virtual returns (uint256) { | ||
return deployerNonce_ + 2; | ||
} | ||
} |
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,73 @@ | ||
// SPDX-License-Identifier: UNLICENSED | ||
|
||
pragma solidity 0.8.23; | ||
|
||
import { Script, console2 } from "../lib/forge-std/src/Script.sol"; | ||
|
||
import { DeployBase } from "./DeployBase.sol"; | ||
|
||
contract DeployProduction is Script, DeployBase { | ||
error DeployerMismatch(address expected, address actual); | ||
|
||
error DeployerNonceTooHigh(); | ||
|
||
error UnexpectedDeployerNonce(); | ||
|
||
error CurrentNonceMismatch(uint64 expected, uint64 actual); | ||
|
||
error ExpectedProxyMismatch(address expected, address actual); | ||
|
||
error ResultingProxyMismatch(address expected, address actual); | ||
|
||
// NOTE: Ensure this is the correct M Token testnet/mainnet address. | ||
address internal constant _M_TOKEN = 0x866A2BF4E572CbcF37D5071A7a58503Bfb36be1b; | ||
|
||
// NOTE: Ensure this is the correct Migration Admin testnet/mainnet address. | ||
address internal constant _MIGRATION_ADMIN = 0x431169728D75bd02f4053435b87D15c8d1FB2C72; | ||
|
||
// NOTE: Ensure this is the correct deployer testnet/mainnet to use. | ||
address internal constant _EXPECTED_DEPLOYER = 0xF2f1ACbe0BA726fEE8d75f3E32900526874740BB; | ||
|
||
// NOTE: Ensure this is the correct nonce to use to deploy the Proxy on testnet/mainnet. | ||
uint256 internal constant _DEPLOYER_PROXY_NONCE = 40; | ||
|
||
// NOTE: Ensure this is the correct expected testnet/mainnet address for the Proxy. | ||
address internal constant _EXPECTED_PROXY = 0x437cc33344a0B27A429f795ff6B469C72698B291; | ||
|
||
function run() external { | ||
address deployer_ = vm.rememberKey(vm.envUint("PRIVATE_KEY")); | ||
|
||
console2.log("Deployer:", deployer_); | ||
|
||
if (deployer_ != _EXPECTED_DEPLOYER) revert DeployerMismatch(_EXPECTED_DEPLOYER, deployer_); | ||
|
||
uint64 currentNonce_ = vm.getNonce(deployer_); | ||
|
||
if (currentNonce_ >= _DEPLOYER_PROXY_NONCE - 1) revert DeployerNonceTooHigh(); | ||
|
||
address expectedProxy_ = getExpectedWrappedMTokenProxy(deployer_, _DEPLOYER_PROXY_NONCE); | ||
|
||
if (expectedProxy_ != _EXPECTED_PROXY) revert ExpectedProxyMismatch(_EXPECTED_PROXY, expectedProxy_); | ||
|
||
vm.startBroadcast(deployer_); | ||
|
||
// Burn nonces until to 1 before `_DEPLOYER_PROXY_NONCE` since implementation is deployed before proxy. | ||
while (currentNonce_ < _DEPLOYER_PROXY_NONCE - 1) { | ||
payable(deployer_).transfer(0); | ||
++currentNonce_; | ||
} | ||
|
||
if (currentNonce_ != vm.getNonce(deployer_)) revert CurrentNonceMismatch(currentNonce_, vm.getNonce(deployer_)); | ||
|
||
if (currentNonce_ != _DEPLOYER_PROXY_NONCE - 1) revert UnexpectedDeployerNonce(); | ||
|
||
(address implementation_, address proxy_) = deploy(_M_TOKEN, _MIGRATION_ADMIN); | ||
|
||
vm.stopBroadcast(); | ||
|
||
console2.log("Wrapped M Implementation address:", implementation_); | ||
console2.log("Wrapped M Proxy address:", proxy_); | ||
|
||
if (proxy_ != _EXPECTED_PROXY) revert ResultingProxyMismatch(_EXPECTED_PROXY, proxy_); | ||
} | ||
} |
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
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,45 @@ | ||
// SPDX-License-Identifier: UNLICENSED | ||
|
||
pragma solidity 0.8.23; | ||
|
||
import { Test } from "../../lib/forge-std/src/Test.sol"; | ||
|
||
import { IWrappedMToken } from "../../src/interfaces/IWrappedMToken.sol"; | ||
import { IMTokenLike } from "../../src/interfaces/IMTokenLike.sol"; | ||
import { IRegistrarLike } from "../../src/interfaces/IRegistrarLike.sol"; | ||
|
||
import { DeployBase } from "../../script/DeployBase.sol"; | ||
|
||
contract Deploy is Test, DeployBase { | ||
address internal constant _TTG_VAULT = 0xdeaDDeADDEaDdeaDdEAddEADDEAdDeadDEADDEaD; | ||
|
||
address internal constant _M_TOKEN = 0x866A2BF4E572CbcF37D5071A7a58503Bfb36be1b; | ||
address internal constant _MIGRATION_ADMIN = 0x431169728D75bd02f4053435b87D15c8d1FB2C72; | ||
address internal constant _DEPLOYER = 0xF2f1ACbe0BA726fEE8d75f3E32900526874740BB; | ||
uint256 internal constant _DEPLOYER_PROXY_NONCE = 40; | ||
address internal constant _EXPECTED_PROXY = 0x437cc33344a0B27A429f795ff6B469C72698B291; | ||
|
||
function test_deploy() external { | ||
// Set nonce to 1 before `_DEPLOYER_PROXY_NONCE` since implementation is deployed before proxy. | ||
vm.setNonce(_DEPLOYER, uint64(_DEPLOYER_PROXY_NONCE) - 1); | ||
|
||
vm.startPrank(_DEPLOYER); | ||
(address implementation_, address proxy_) = deploy(_M_TOKEN, _MIGRATION_ADMIN); | ||
vm.stopPrank(); | ||
|
||
// Wrapped M Token Implementation assertions | ||
assertEq(implementation_, getExpectedWrappedMTokenImplementation(_DEPLOYER, 39)); | ||
assertEq(IWrappedMToken(implementation_).migrationAdmin(), _MIGRATION_ADMIN); | ||
assertEq(IWrappedMToken(implementation_).mToken(), _M_TOKEN); | ||
assertEq(IWrappedMToken(implementation_).registrar(), IMTokenLike(_M_TOKEN).ttgRegistrar()); | ||
assertEq(IWrappedMToken(implementation_).vault(), IRegistrarLike(IMTokenLike(_M_TOKEN).ttgRegistrar()).vault()); | ||
|
||
// // Wrapped M Token Proxy assertions | ||
assertEq(proxy_, getExpectedWrappedMTokenProxy(_DEPLOYER, 39)); | ||
assertEq(proxy_, _EXPECTED_PROXY); | ||
assertEq(IWrappedMToken(proxy_).migrationAdmin(), _MIGRATION_ADMIN); | ||
assertEq(IWrappedMToken(proxy_).mToken(), _M_TOKEN); | ||
assertEq(IWrappedMToken(proxy_).registrar(), IMTokenLike(_M_TOKEN).ttgRegistrar()); | ||
assertEq(IWrappedMToken(proxy_).vault(), IRegistrarLike(IMTokenLike(_M_TOKEN).ttgRegistrar()).vault()); | ||
} | ||
} |
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