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: MIT
pragma solidity ^0.8.9;
import "@cube3/Cube3Protection.sol";
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
contract Cube3ProtectedErc20 is ERC20, Cube3Protection {
constructor(address _router)
Cube3Protection(_router, msg.sender, true)
ERC20("Cube3Token", "CTK")
{
_mint(msg.sender, 10000 * 10**decimals());
}
function mintCube3TokenBlockByName(
address to,
uint256 amount,
bytes calldata cube3SecurePayload
) public cube3Protected(cube3SecurePayload) {
_mint(to, amount);
}
}
// SPDX-License-Identifier: MIT
pragma solidity 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";
contract Cube3ProtectedErc20UUPS is Cube3ProtectionUpgradeable, ERC20Upgradeable, UUPSUpgradeable, OwnableUpgradeable {
function initialize(address router, address admin, bool checkProtection) initializer public {
// 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)
internal
virtual
override
onlyOwner
{}
function mintCube3Protected(
address to,
uint256 amount,
bytes calldata cube3SecurePayload
) public cube3Protected(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: MIT
pragma solidity 0.8.19;
import "../src/Cube3ProtectedErc20UUPS.sol";
import "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol";
import "forge-std/Script.sol";
contract DeployUUPSProxy is Script {
function run() public {
address _implementation = YOUR-IMPLEMENTATION-ADDRESS; // Replace with your protected contract address
address _cube3RouterProxy = CUBE3-ROUTER-ADDRESS; // Replace with CUBE3 Router address
vm.startBroadcast();
// Deploy the proxy contract with the implementation address and initializer
ERC1967Proxy cube3ProtectedTokenProxy = new ERC1967Proxy(_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:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;
import "@cube3/Cube3Protection.sol";
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
contract Cube3ProtectedErc20 is ERC20, Cube3Protection {
constructor(address _router)
Cube3Protection(_router, msg.sender, true)
ERC20("Cube3Token", "CTK")
{
_mint(msg.sender, 10000 * 10**decimals());
}
function mintCube3TokenBlockByName(
address to,
uint256 amount,
bytes calldata cube3SecurePayload
) public cube3Protected(cube3SecurePayload) {
_mint(to, amount);
}
}
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: MIT
pragma solidity 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";
contract Cube3ProtectedErc20UUPS is Cube3ProtectionUpgradeable, ERC20Upgradeable, UUPSUpgradeable, OwnableUpgradeable {
function initialize(address router, address admin, bool checkProtection) initializer public {
// 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)
internal
virtual
override
onlyOwner
{}
function mintCube3Protected(
address to,
uint256 amount,
bytes calldata cube3SecurePayload
) public cube3Protected(cube3SecurePayload) {
_mint(to, amount);
}
}