Skip to content

Commit

Permalink
Refactor SealedBidTokenSale contract to support UUPS upgradeability, …
Browse files Browse the repository at this point in the history
…update imports, and adjust unit tests for proxy initialization.
  • Loading branch information
ylv-io committed Feb 8, 2025
1 parent afe8f82 commit d16c447
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 7 deletions.
29 changes: 24 additions & 5 deletions src/apps/SealedBidTokenSale.sol
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;

import {Ownable} from "@openzeppelin-5.0.1/contracts/access/Ownable.sol";
import {OwnableUpgradeable} from "@openzeppelin-5.0.1/contracts-upgradeable/access/OwnableUpgradeable.sol";
import {Initializable} from "@openzeppelin-5.0.1/contracts-upgradeable/proxy/utils/Initializable.sol";
import {ReentrancyGuardUpgradeable} from
"@openzeppelin-5.0.1/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol";
import {UUPSUpgradeable} from "@openzeppelin-5.0.1/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
import {IERC20} from "@openzeppelin-5.0.1/contracts/token/ERC20/IERC20.sol";
import {ReentrancyGuard} from "@openzeppelin-5.0.1/contracts/utils/ReentrancyGuard.sol";
import {MerkleProof} from "@openzeppelin-5.0.1/contracts/utils/cryptography/MerkleProof.sol";
import {SafeERC20} from "@openzeppelin-5.0.1/contracts/token/ERC20/utils/SafeERC20.sol";

Expand All @@ -18,7 +21,7 @@ import {SafeERC20} from "@openzeppelin-5.0.1/contracts/token/ERC20/utils/SafeERC
* - Full refunds if minimum cap not reached
* - Early participation window for first 700 emissaries
*/
contract SealedBidTokenSale is Ownable, ReentrancyGuard {
contract SealedBidTokenSale is Initializable, UUPSUpgradeable, OwnableUpgradeable, ReentrancyGuardUpgradeable {
using SafeERC20 for IERC20;

/* ============ Struct ============ */
Expand Down Expand Up @@ -172,7 +175,6 @@ contract SealedBidTokenSale is Ownable, ReentrancyGuard {
mapping(address => bool) public isEmissary;

/* ============ Constructor ============ */

/**
* @notice Initializes the token sale with required parameters
* @param _saleToken Address of the token being sold
Expand All @@ -188,7 +190,9 @@ contract SealedBidTokenSale is Ownable, ReentrancyGuard {
uint256 _preStartTime,
uint256 _startTime,
uint256 _minimumCap
) Ownable(msg.sender) {
) {
_disableInitializers();

if (_saleToken == address(0)) revert InvalidSaleTokenAddress(_saleToken);
if (_treasury == address(0)) revert InvalidTreasuryAddress(_treasury);
if (_preStartTime >= _startTime) revert InvalidTimeConfiguration();
Expand All @@ -201,6 +205,21 @@ contract SealedBidTokenSale is Ownable, ReentrancyGuard {
minimumCap = _minimumCap;
}

/// @dev initialize the proxy
function initialize() external virtual initializer {
__Ownable_init(msg.sender);
__UUPSUpgradeable_init();
}

/**
* @dev Authorize the upgrade. Only by an owner.
* @param newImplementation address of the new implementation
*/
// This function is called by the proxy contract when the factory is upgraded
function _authorizeUpgrade(address newImplementation) internal view override onlyOwner {

Check warning on line 219 in src/apps/SealedBidTokenSale.sol

View check run for this annotation

Codecov / codecov/patch

src/apps/SealedBidTokenSale.sol#L219

Added line #L219 was not covered by tests
(newImplementation);
}

/* ============ User Functions ============ */

/**
Expand Down
7 changes: 5 additions & 2 deletions test/unit/apps/SealedBidTokenSale.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
pragma solidity ^0.8.18;

import {Ownable} from "@openzeppelin-5.0.1/contracts/access/Ownable.sol";
import {UUPSProxy} from "@kinto-core-test/helpers/UUPSProxy.sol";
import {Test} from "forge-std/Test.sol";
import {SealedBidTokenSale} from "@kinto-core/apps/SealedBidTokenSale.sol";
import {ERC20Mock} from "@kinto-core-test/helpers/ERC20Mock.sol";
Expand Down Expand Up @@ -38,9 +39,11 @@ contract SealedBidTokenSaleTest is SharedSetup {
usdc = new ERC20Mock("USDC", "USDC", 6);
saleToken = new ERC20Mock("K", "KINTO", 18);

// Deploy sale contract with admin as owner
vm.prank(admin);
sale = new SealedBidTokenSale(address(saleToken), TREASURY, address(usdc), preStartTime, startTime, MIN_CAP);
vm.startPrank(admin);
sale = SealedBidTokenSale(address(new UUPSProxy{salt: 0}(address(sale), "")));
sale.initialize();
vm.stopPrank();

// Setup Merkle tree with alice and bob
bytes32[] memory leaves = new bytes32[](2);
Expand Down

0 comments on commit d16c447

Please sign in to comment.