To deploy a non-upgradeable example below, you need to pass the router address into its constructor (find the CUBE3 Router address here). Let's deploy an example below:
// SPDX-License-Identifier: MITpragmasolidity 0.8.19;import"@openzeppelin-upgradeable/contracts/token/ERC20/ERC20Upgradeable.sol";import"@openzeppelin-upgradeable/contracts/proxy/utils/UUPSUpgradeable.sol";import"@openzeppelin-upgradeable/contracts/access/OwnableUpgradeable.sol";import"@cube3/upgradeable/Cube3ProtectionUpgradeable.sol";contractCube3ProtectedErc20UUPSisCube3ProtectionUpgradeable, ERC20Upgradeable, UUPSUpgradeable, OwnableUpgradeable {functioninitialize(address router,address admin,bool checkProtection) initializerpublic {// In this scenario, the contract owner is the same account as the integration's admin, which// has privileged access to the router.__Cube3ProtectionUpgradeable_init(router, admin, checkProtection);__UUPSUpgradeable_init();__ERC20_init("Cube3ProtectedToken","CTK");_mint(admin,10000*10**decimals()); }function_authorizeUpgrade(address newImplementation)internalvirtualoverrideonlyOwner {}functionmintCube3Protected(address to,uint256 amount,bytescalldata cube3SecurePayload ) publiccube3Protected(cube3SecurePayload) {_mint(to, amount); }}
Now that our implementation is deployed, save its address. Next, create a foundry script script/deployProxy.s.sol and paste the code below (update your implementation address):
// SPDX-License-Identifier: MITpragmasolidity 0.8.19;import"../src/Cube3ProtectedErc20UUPS.sol";import"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol";import"forge-std/Script.sol";contractDeployUUPSProxyisScript {functionrun() public {address _implementation = YOUR-IMPLEMENTATION-ADDRESS; // Replace with your protected contract addressaddress _cube3RouterProxy = CUBE3-ROUTER-ADDRESS; // Replace with CUBE3 Router address vm.startBroadcast();// Deploy the proxy contract with the implementation address and initializer ERC1967Proxy cube3ProtectedTokenProxy =newERC1967Proxy(_implementation, abi.encodeCall(Cube3ProtectedErc20UUPS.initialize, (_cube3RouterProxy, msg.sender,true))); vm.stopBroadcast();// Log the proxy address console.log("UUPS Proxy Address:",address(cube3ProtectedTokenProxy)); }}
To run this script, run the following in your cmd:
To deploy a non-upgradeable example below, you need to pass the router address into its constructor (find the CUBE3 Router address here). Let's deploy an example below:
import {ethers} from"hardhat";asyncfunctionmain() {const [deployer] =awaitethers.getSigners();console.log("Deploying contracts with the account:",deployer.address);constCube3ProtectedErc20=awaitethers.getContractFactory("Cube3ProtectedErc20");constcontract=awaitCube3ProtectedErc20.deploy("Router proxy address");awaitcontract.waitForDeployment();constaddress=awaitcontract.getAddress()console.log(`Cube3ProtectedErc20 deployed to: ${address}`);}main().catch((error) => {console.error(error);process.exitCode =1;});
Lastly, to deploy Cube3ProtectedErc20 contract, run the following in cmd:
npx hardhat run scripts/deploy.ts --network sepolia
b. Upgradeable
For upgradeable contracts, we have two steps:
Deploy implementation
Deploy Proxy that points to implementation
Let's deploy the implementation example below:
// SPDX-License-Identifier: MITpragmasolidity 0.8.19;import"@openzeppelin-upgradeable/contracts/token/ERC20/ERC20Upgradeable.sol";import"@openzeppelin-upgradeable/contracts/proxy/utils/UUPSUpgradeable.sol";import"@openzeppelin-upgradeable/contracts/access/OwnableUpgradeable.sol";import"@cube3/upgradeable/Cube3ProtectionUpgradeable.sol";contractCube3ProtectedErc20UUPSisCube3ProtectionUpgradeable, ERC20Upgradeable, UUPSUpgradeable, OwnableUpgradeable {functioninitialize(address router,address admin,bool checkProtection) initializerpublic {// In this scenario, the contract owner is the same account as the integration's admin, which// has privileged access to the router.__Cube3ProtectionUpgradeable_init(router, admin, checkProtection);__UUPSUpgradeable_init();__ERC20_init("Cube3ProtectedToken","CTK");_mint(admin,10000*10**decimals()); }function_authorizeUpgrade(address newImplementation)internalvirtualoverrideonlyOwner {}functionmintCube3Protected(address to,uint256 amount,bytescalldata cube3SecurePayload ) publiccube3Protected(cube3SecurePayload) {_mint(to, amount); }}