Sitelet https://github.com/roycoprotocol/royco-iam/commit/c15243fc899d8dc3fa7ce8d9a9322b9d03de2528
Skip to content

Commit c15243f

Browse files
script: 0x0e27Ee Owner
1 parent 5c16bc6 commit c15243f

4 files changed

Lines changed: 283 additions & 2 deletions

File tree

‎.env.example‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@ PRIVATE_KEY=
33
EXPLORER_KEY_1=
44
EXPLORER_KEY_42161=
55
EXPLORER_KEY_8453=
6-
EXPLORER_KEY_80084=
6+
EXPLORER_KEY_80084=
7+
EXPLORER_KEY_146=

‎foundry.toml‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,5 @@ ignore = ["libs/*", "*.t.sol"]
3737
42161 = { key = "${EXPLORER_KEY_42161}" }
3838
8453 = { key = "${EXPLORER_KEY_8453}" }
3939
80084 = { key = "${EXPLORER_KEY_80084}", url = "https://api.routescan.io/v2/network/testnet/evm/80084/etherscan/api" }
40-
80000 = { key = "${EXPLORER_KEY_80084}", url = "https://api.routescan.io/v2/network/testnet/evm/80000/etherscan/api" }
40+
80000 = { key = "${EXPLORER_KEY_80084}", url = "https://api.routescan.io/v2/network/testnet/evm/80000/etherscan/api" }
41+
146 = { key = "${EXPLORER_KEY_146}", url = "https://api.sonicscan.org/api" }
Lines changed: 279 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,279 @@
1+
// SPDX-License-Identifier: UNLICENSED
2+
3+
// Usage: source .env && forge script ./script/Deploy.Deterministic.s.sol --rpc-url=$SEPOLIA_RPC_URL --broadcast --etherscan-api-key=$ETHERSCAN_API_KEY --verify
4+
5+
pragma solidity ^0.8.0;
6+
7+
import "forge-std/Script.sol";
8+
9+
import { WrappedVault } from "../src/WrappedVault.sol";
10+
import { WrappedVaultFactory } from "../src/WrappedVaultFactory.sol";
11+
import { Points } from "../src/Points.sol";
12+
import { PointsFactory } from "../src/PointsFactory.sol";
13+
import { VaultMarketHub } from "../src/VaultMarketHub.sol";
14+
import { RecipeMarketHub } from "../src/RecipeMarketHub.sol";
15+
import { WeirollWallet } from "../src/WeirollWallet.sol";
16+
17+
import { MockERC20 } from "test/mocks/MockERC20.sol";
18+
import { MockERC4626 } from "test/mocks/MockERC4626.sol";
19+
20+
// Deployer
21+
address constant CREATE2_FACTORY_ADDRESS = 0x4e59b44847b379578588920cA78FbF26c0B4956C;
22+
23+
// Deployment Salts
24+
string constant POINTS_FACTORY_SALT = "ROYCO_POINTS_FACTORY_458371a243a7299e99f3fbfb67799eaaf734ccaf";
25+
string constant WRAPPED_VAULT_SALT = "ROYCO_WRAPPED_VAULT_627001f37bde0b6f93a8a618530963e24ea2b9af";
26+
string constant WRAPPED_VAULT_FACTORY_SALT = "ROYCO_WRAPPED_VAULT_FACTORY_5414c04eeefec8db6047b9508f5c07245a5e7c81";
27+
string constant WEIROLL_WALLET_SALT = "ROYCO_WEIROLL_WALLET_458371a243a7299e99f3fbfb67799eaaf734ccaf";
28+
string constant VAULT_MARKET_HUB_SALT = "ROYCO_VAULT_MARKET_HUB_458371a243a7299e99f3fbfb67799eaaf734ccaf";
29+
string constant RECIPE_MARKET_HUB_SALT = "ROYCO_RECIPE_MARKET_HUB_458371a243a7299e99f3fbfb67799eaaf734ccaf";
30+
31+
// Deployment Configuration
32+
address constant ROYCO_OWNER = 0x0e27Ee92E591D4fB7A6237CBA4c7b4B81bBBDCa8;
33+
address constant PROTOCOL_FEE_RECIPIENT = 0x0e27Ee92E591D4fB7A6237CBA4c7b4B81bBBDCa8;
34+
uint256 constant PROTOCOL_FEE = 0;
35+
uint256 constant MINIMUM_FRONTEND_FEE = 0.005e18;
36+
37+
// Expected Deployment Addresses
38+
address constant EXPECTED_POINTS_FACTORY_ADDRESS = 0xD3B5beD62038d520FE659C01B03e2727377c8B8d;
39+
address constant EXPECTED_WRAPPED_VAULT_ADDRESS = 0xb0a3960B115E0999F33e8AfD4a11f16e04e2bf33;
40+
address constant EXPECTED_WRAPPED_VAULT_FACTORY_ADDRESS = 0x7212d98A88D44f714FD29dd980cb846be8E7491a;
41+
address constant EXPECTED_WEIROLL_WALLET_ADDRESS = 0x40a1c08084671E9A799B73853E82308225309Dc0;
42+
address constant EXPECTED_VAULT_MARKET_HUB_ADDRESS = 0x1e3fCccbafDBdf3cB17b7470c8A6cC64eb5f94A2;
43+
address constant EXPECTED_RECIPE_MARKET_HUB_ADDRESS = 0xFcc593aD3705EBcd72eC961c63eb484BE795BDbD;
44+
45+
bytes32 constant WRAPPED_VAULT_FACTORY_IMPL_SLOT = bytes32(uint256(2));
46+
47+
contract DeployDeterministic is Script {
48+
error Create2DeployerNotDeployed();
49+
50+
error DeploymentFailed(bytes reason);
51+
error NotDeployedToExpectedAddress(address expected, address actual);
52+
error AddressDoesNotContainBytecode(address addr);
53+
error UnexpectedDeploymentAddress(address expected, address actual);
54+
55+
error PointsFactoryOwnerIncorrect(address expected, address actual);
56+
57+
error WrappedVaultFactoryProtocolFeeRecipientIncorrect(address expected, address actual);
58+
error WrappedVaultFactoryProtocolFeeIncorrect(uint256 expected, uint256 actual);
59+
error WrappedVaultFactoryMinimumFrontendFeeIncorrect(uint256 expected, uint256 actual);
60+
error WrappedVaultFactoryOwnerIncorrect(address expected, address actual);
61+
error WrappedVaultFactoryPointsFactoryIncorrect(address expected, address actual);
62+
error WrappedVaultFactoryImplementationIncorrect(address expected, address actual);
63+
64+
error VaultMarketHubOwnerIncorrect(address expected, address actual);
65+
66+
error RecipeMarketHubWeirollWalletImplementationIncorrect(address expected, address actual);
67+
error RecipeMarketHubProtocolFeeIncorrect(uint256 expected, uint256 actual);
68+
error RecipeMarketHubMinimumFrontendFeeIncorrect(uint256 expected, uint256 actual);
69+
error RecipeMarketHubOwnerIncorrect(address expected, address actual);
70+
error RecipeMarketHubPointsFactoryIncorrect(address expected, address actual);
71+
72+
function _generateUint256SaltFromString(string memory _salt) internal pure returns (uint256) {
73+
return uint256(keccak256(abi.encodePacked(_salt)));
74+
}
75+
76+
function _generateDeterminsticAddress(string memory _salt, bytes memory _creationCode) internal pure returns (address) {
77+
uint256 salt = _generateUint256SaltFromString(_salt);
78+
bytes32 hash = keccak256(abi.encodePacked(bytes1(0xff), CREATE2_FACTORY_ADDRESS, salt, keccak256(_creationCode)));
79+
return address(uint160(uint256(hash)));
80+
}
81+
82+
function _checkDeployer() internal view {
83+
if (CREATE2_FACTORY_ADDRESS.code.length == 0) {
84+
revert Create2DeployerNotDeployed();
85+
}
86+
}
87+
88+
function _deploy(string memory _salt, bytes memory _creationCode) internal returns (address deployedAddress) {
89+
(bool success, bytes memory data) = CREATE2_FACTORY_ADDRESS.call(abi.encodePacked(_generateUint256SaltFromString(_salt), _creationCode));
90+
91+
if (!success) {
92+
revert DeploymentFailed(data);
93+
}
94+
95+
assembly ("memory-safe") {
96+
deployedAddress := shr(0x60, mload(add(data, 0x20)))
97+
}
98+
}
99+
100+
function _deployWithSanityChecks(string memory _salt, bytes memory _creationCode) internal returns (address, bool isAlreadyDeployed) {
101+
address expectedAddress = _generateDeterminsticAddress(_salt, _creationCode);
102+
103+
if (address(expectedAddress).code.length != 0) {
104+
console2.log("contract already deployed at: ", expectedAddress);
105+
return (expectedAddress, true);
106+
}
107+
108+
address addr = _deploy(_salt, _creationCode);
109+
110+
if (addr != expectedAddress) {
111+
revert NotDeployedToExpectedAddress(expectedAddress, addr);
112+
}
113+
114+
if (address(addr).code.length == 0) {
115+
revert AddressDoesNotContainBytecode(addr);
116+
}
117+
118+
return (addr, false);
119+
}
120+
121+
function _verifyPointsFactoryDeployment(PointsFactory _pointsFactory) internal view {
122+
if (address(_pointsFactory) != EXPECTED_POINTS_FACTORY_ADDRESS) {
123+
revert UnexpectedDeploymentAddress(EXPECTED_POINTS_FACTORY_ADDRESS, address(_pointsFactory));
124+
}
125+
126+
if (_pointsFactory.owner() != ROYCO_OWNER) revert PointsFactoryOwnerIncorrect(ROYCO_OWNER, _pointsFactory.owner());
127+
}
128+
129+
function _verifyWrappedVaultDeployment(WrappedVault _wrappedVault) internal pure {
130+
if (address(_wrappedVault) != EXPECTED_WRAPPED_VAULT_ADDRESS) {
131+
revert UnexpectedDeploymentAddress(EXPECTED_WRAPPED_VAULT_ADDRESS, address(_wrappedVault));
132+
}
133+
}
134+
135+
function _verifyWrappedVaultFactoryDeployment(WrappedVaultFactory _wrappedVaultFactory, PointsFactory _pointsFactory, WrappedVault _impl) internal view {
136+
if (address(_wrappedVaultFactory) != EXPECTED_WRAPPED_VAULT_FACTORY_ADDRESS) {
137+
revert UnexpectedDeploymentAddress(EXPECTED_WRAPPED_VAULT_FACTORY_ADDRESS, address(_wrappedVaultFactory));
138+
}
139+
if (_wrappedVaultFactory.protocolFeeRecipient() != PROTOCOL_FEE_RECIPIENT) {
140+
revert WrappedVaultFactoryProtocolFeeRecipientIncorrect(PROTOCOL_FEE_RECIPIENT, _wrappedVaultFactory.protocolFeeRecipient());
141+
}
142+
if (_wrappedVaultFactory.protocolFee() != PROTOCOL_FEE) {
143+
revert WrappedVaultFactoryProtocolFeeIncorrect(PROTOCOL_FEE, _wrappedVaultFactory.protocolFee());
144+
}
145+
if (_wrappedVaultFactory.minimumFrontendFee() != MINIMUM_FRONTEND_FEE) {
146+
revert WrappedVaultFactoryMinimumFrontendFeeIncorrect(MINIMUM_FRONTEND_FEE, _wrappedVaultFactory.minimumFrontendFee());
147+
}
148+
if (_wrappedVaultFactory.owner() != ROYCO_OWNER) {
149+
revert WrappedVaultFactoryOwnerIncorrect(ROYCO_OWNER, _wrappedVaultFactory.owner());
150+
}
151+
if (_wrappedVaultFactory.pointsFactory() != address(_pointsFactory)) {
152+
revert WrappedVaultFactoryPointsFactoryIncorrect(address(_pointsFactory), _wrappedVaultFactory.pointsFactory());
153+
}
154+
address actualImpl = address(uint160(uint256(vm.load(address(_wrappedVaultFactory), WRAPPED_VAULT_FACTORY_IMPL_SLOT))));
155+
if (actualImpl != address(_impl)) {
156+
revert WrappedVaultFactoryImplementationIncorrect(address(_impl), actualImpl);
157+
}
158+
}
159+
160+
function _verifyWeirollWalletDeployment(WeirollWallet _weirollWallet) internal pure {
161+
if (address(_weirollWallet) != EXPECTED_WEIROLL_WALLET_ADDRESS) {
162+
revert UnexpectedDeploymentAddress(EXPECTED_WEIROLL_WALLET_ADDRESS, address(_weirollWallet));
163+
}
164+
}
165+
166+
function _verifyVaultMarketHubDeployment(VaultMarketHub _vaultMarketHub) internal view {
167+
if (address(_vaultMarketHub) != EXPECTED_VAULT_MARKET_HUB_ADDRESS) {
168+
revert UnexpectedDeploymentAddress(EXPECTED_VAULT_MARKET_HUB_ADDRESS, address(_vaultMarketHub));
169+
}
170+
if (_vaultMarketHub.owner() != ROYCO_OWNER) revert VaultMarketHubOwnerIncorrect(ROYCO_OWNER, _vaultMarketHub.owner());
171+
}
172+
173+
function _verifyRecipeMarketHubDeployment(RecipeMarketHub _recipeMarketHub, WeirollWallet _weirollWallet, PointsFactory _pointsFactory) internal view {
174+
if (address(_recipeMarketHub) != EXPECTED_RECIPE_MARKET_HUB_ADDRESS) {
175+
revert UnexpectedDeploymentAddress(EXPECTED_RECIPE_MARKET_HUB_ADDRESS, address(_recipeMarketHub));
176+
}
177+
if (_recipeMarketHub.WEIROLL_WALLET_IMPLEMENTATION() != address(_weirollWallet)) {
178+
revert RecipeMarketHubWeirollWalletImplementationIncorrect(address(_weirollWallet), _recipeMarketHub.WEIROLL_WALLET_IMPLEMENTATION());
179+
}
180+
if (_recipeMarketHub.protocolFee() != PROTOCOL_FEE) {
181+
revert RecipeMarketHubProtocolFeeIncorrect(PROTOCOL_FEE, _recipeMarketHub.protocolFee());
182+
}
183+
if (_recipeMarketHub.minimumFrontendFee() != MINIMUM_FRONTEND_FEE) {
184+
revert RecipeMarketHubMinimumFrontendFeeIncorrect(MINIMUM_FRONTEND_FEE, _recipeMarketHub.minimumFrontendFee());
185+
}
186+
if (_recipeMarketHub.owner() != ROYCO_OWNER) {
187+
revert RecipeMarketHubOwnerIncorrect(ROYCO_OWNER, _recipeMarketHub.owner());
188+
}
189+
if (_recipeMarketHub.POINTS_FACTORY() != address(_pointsFactory)) {
190+
revert RecipeMarketHubPointsFactoryIncorrect(address(_pointsFactory), _recipeMarketHub.POINTS_FACTORY());
191+
}
192+
}
193+
194+
function run() external {
195+
uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY");
196+
address deployerAddress = vm.addr(deployerPrivateKey);
197+
198+
console2.log("Deploying with address: ", deployerAddress);
199+
console2.log("Deployer Balance: ", address(deployerAddress).balance);
200+
201+
vm.startBroadcast(deployerPrivateKey);
202+
203+
_checkDeployer();
204+
console2.log("Deployer is ready\n");
205+
206+
// Deploy PointsFactory
207+
console2.log("Deploying PointsFactory");
208+
bytes memory pointsFactoryCreationCode = abi.encodePacked(vm.getCode("PointsFactory"), abi.encode(ROYCO_OWNER));
209+
(address deployedContractAddress, bool isAlreadyDeployed) = _deployWithSanityChecks(POINTS_FACTORY_SALT, pointsFactoryCreationCode);
210+
PointsFactory pointsFactory = PointsFactory(deployedContractAddress);
211+
if (!isAlreadyDeployed) {
212+
console2.log("Verifying PointsFactory deployment");
213+
_verifyPointsFactoryDeployment(pointsFactory);
214+
}
215+
console2.log("PointsFactory deployed at: ", address(pointsFactory), "\n");
216+
217+
// Deploy WrappedVault
218+
console2.log("Deploying WrappedVault");
219+
bytes memory wrappedVaultCreationCode = abi.encodePacked(vm.getCode("WrappedVault"));
220+
(deployedContractAddress, isAlreadyDeployed) = _deployWithSanityChecks(WRAPPED_VAULT_SALT, wrappedVaultCreationCode);
221+
WrappedVault wrappedVault = WrappedVault(deployedContractAddress);
222+
if (!isAlreadyDeployed) {
223+
console2.log("Verifying WrappedVault deployment");
224+
_verifyWrappedVaultDeployment(wrappedVault);
225+
}
226+
console2.log("WrappedVault deployed at: ", address(wrappedVault), "\n");
227+
228+
// Deploy WrappedVaultFactory
229+
console2.log("Deploying WrappedVaultFactory");
230+
bytes memory wrappedVaultFactoryCreationCode = abi.encodePacked(
231+
vm.getCode("WrappedVaultFactory"),
232+
abi.encode(wrappedVault, PROTOCOL_FEE_RECIPIENT, PROTOCOL_FEE, MINIMUM_FRONTEND_FEE, ROYCO_OWNER, address(pointsFactory))
233+
);
234+
(deployedContractAddress, isAlreadyDeployed) = _deployWithSanityChecks(WRAPPED_VAULT_FACTORY_SALT, wrappedVaultFactoryCreationCode);
235+
WrappedVaultFactory wrappedVaultFactory = WrappedVaultFactory(deployedContractAddress);
236+
if (!isAlreadyDeployed) {
237+
console2.log("Verifying WrappedVaultFactory deployment");
238+
_verifyWrappedVaultFactoryDeployment(wrappedVaultFactory, pointsFactory, WrappedVault(wrappedVault));
239+
}
240+
console2.log("WrappedVaultFactory deployed at: ", address(wrappedVaultFactory), "\n");
241+
242+
// Deploy WeirollWallet
243+
console2.log("Deploying WeirollWallet");
244+
bytes memory weirollWalletCreationCode = abi.encodePacked(vm.getCode("WeirollWallet"));
245+
(deployedContractAddress, isAlreadyDeployed) = _deployWithSanityChecks(WEIROLL_WALLET_SALT, weirollWalletCreationCode);
246+
WeirollWallet weirollWallet = WeirollWallet(payable(deployedContractAddress));
247+
if (!isAlreadyDeployed) {
248+
console2.log("Verifying WeirollWallet deployment");
249+
_verifyWeirollWalletDeployment(weirollWallet);
250+
}
251+
console2.log("WeirollWallet deployed at: ", address(weirollWallet), "\n");
252+
253+
// Deploy VaultMarketHub
254+
console2.log("Deploying VaultMarketHub");
255+
bytes memory vaultMarketHubCreationCode = abi.encodePacked(vm.getCode("VaultMarketHub"), abi.encode(ROYCO_OWNER));
256+
(deployedContractAddress, isAlreadyDeployed) = _deployWithSanityChecks(VAULT_MARKET_HUB_SALT, vaultMarketHubCreationCode);
257+
VaultMarketHub vaultMarketHub = VaultMarketHub(deployedContractAddress);
258+
if (!isAlreadyDeployed) {
259+
console2.log("Verifying VaultMarketHub deployment");
260+
_verifyVaultMarketHubDeployment(vaultMarketHub);
261+
}
262+
console2.log("VaultMarketHub deployed at: ", address(vaultMarketHub), "\n");
263+
264+
// Deploy RecipeMarketHub
265+
console2.log("Deploying RecipeMarketHub");
266+
bytes memory recipeMarketHubCreationCode = abi.encodePacked(
267+
vm.getCode("RecipeMarketHub"), abi.encode(address(weirollWallet), PROTOCOL_FEE, MINIMUM_FRONTEND_FEE, ROYCO_OWNER, address(pointsFactory))
268+
);
269+
(deployedContractAddress, isAlreadyDeployed) = _deployWithSanityChecks(RECIPE_MARKET_HUB_SALT, recipeMarketHubCreationCode);
270+
RecipeMarketHub recipeMarketHub = RecipeMarketHub(deployedContractAddress);
271+
if (!isAlreadyDeployed) {
272+
console2.log("Verifying RecipeMarketHub deployment");
273+
_verifyRecipeMarketHubDeployment(recipeMarketHub, weirollWallet, pointsFactory);
274+
}
275+
console2.log("RecipeMarketHub deployed at: ", address(recipeMarketHub), "\n");
276+
277+
vm.stopBroadcast();
278+
}
279+
}
File renamed without changes.

0 commit comments

Comments
 (0)