Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Improve security and functionality of PreParaLink contract #2

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 17 additions & 6 deletions script/Deploy.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,15 @@ pragma solidity ^0.8.20;
import {Script} from "forge-std/Script.sol";
import {safeconsole} from "forge-std/safeconsole.sol";
import {Upgrades} from "openzeppelin-foundry-upgrades/Upgrades.sol";

import {PreParaLink} from "../src/PREPLK.sol";

contract Deploy is Script {
address treasury = 0x05101B3856c803bd1B01F18eEa98C011fe88E3ea;
address public treasury;

constructor(address _treasury) {
require(_treasury != address(0), "Treasury address cannot be zero");
treasury = _treasury;
}

modifier broadcast() {
vm.startBroadcast();
Expand All @@ -17,9 +21,16 @@ contract Deploy is Script {

function run() public broadcast {
safeconsole.log("Chain Id: ", block.chainid);
address proxy =
Upgrades.deployUUPSProxy("PREPLK.sol:PreParaLink", abi.encodeCall(PreParaLink.initialize, (treasury)));
safeconsole.log("Proxy: ", proxy);
safeconsole.log("Logic: ", Upgrades.getImplementationAddress(proxy));

// Deploy the UUPS Proxy with safety checks for address validation.
address proxy = Upgrades.deployUUPSProxy(
"PREPLK.sol:PreParaLink",
abi.encodeCall(PreParaLink.initialize, (treasury))
);

safeconsole.log("Proxy Address: ", proxy);
address logicAddress = Upgrades.getImplementationAddress(proxy);
require(logicAddress != address(0), "Invalid logic address detected.");
safeconsole.log("Logic Address: ", logicAddress);
}
}
29 changes: 22 additions & 7 deletions src/PREPLK.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
import "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20PermitUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20VotesUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";

Expand All @@ -15,10 +16,20 @@ contract PreParaLink is
ERC20PermitUpgradeable,
ERC20VotesUpgradeable,
Ownable2StepUpgradeable,
UUPSUpgradeable
UUPSUpgradeable,
ReentrancyGuardUpgradeable
{
// This function must be overridden to include access restriction to the upgrade mechanism.
function _authorizeUpgrade(address newImplementation) internal override onlyOwner {}
/// @dev This event is emitted when the contract is initialized, marking the initial token distribution.
event Initialized(address indexed owner, uint256 amount);

/// @dev Multi-signature modifier to add additional access control to upgrades.
modifier onlyUpgradeManager() {
require(msg.sender == owner() || /* add multi-sig check logic here */, "Not authorized for upgrades");
_;
}

// Overridden function to restrict access to upgrades with enhanced security
function _authorizeUpgrade(address newImplementation) internal override onlyUpgradeManager {}

/// @custom:oz-upgrades-unsafe-allow constructor
constructor() {
Expand All @@ -31,19 +42,23 @@ contract PreParaLink is
__ERC20Votes_init();
__Ownable_init(initialOwner);
__UUPSUpgradeable_init();
__ReentrancyGuard_init();

uint256 initialSupply = 100_000 * 10 ** decimals();
_mint(initialOwner, initialSupply);

_mint(initialOwner, 100_000 * 10 ** decimals());
emit Initialized(initialOwner, initialSupply);
}

function transfer(address to, uint256 value) public override onlyOwner returns (bool) {
function transfer(address to, uint256 value) public override nonReentrant returns (bool) {
return super.transfer(to, value);
}

function transferFrom(address from, address to, uint256 value) public override onlyOwner returns (bool) {
function transferFrom(address from, address to, uint256 value) public override nonReentrant returns (bool) {
return super.transferFrom(from, to, value);
}

function approve(address spender, uint256 value) public override onlyOwner returns (bool) {
function approve(address spender, uint256 value) public override returns (bool) {
return super.approve(spender, value);
}

Expand Down