From e0f6925bc3ce45b3287c017576a3dfd2060b9ef3 Mon Sep 17 00:00:00 2001 From: Andrew Chiaramonte Date: Thu, 24 Oct 2024 17:38:37 -0400 Subject: [PATCH] =?UTF-8?q?=F0=9F=91=B7=20add=20setAuctionCooldown=20and?= =?UTF-8?q?=20make=20vault=20ownable?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- script/Deploy.s.sol | 3 ++- src/KSXVault.sol | 24 ++++++++++++++++++++++-- test/KSXVault.t.sol | 4 ++++ test/utils/Bootstrap.sol | 5 +++-- 4 files changed, 31 insertions(+), 5 deletions(-) diff --git a/script/Deploy.s.sol b/script/Deploy.s.sol index d5d5163..4cb83f8 100644 --- a/script/Deploy.s.sol +++ b/script/Deploy.s.sol @@ -22,6 +22,7 @@ import {Script} from "lib/forge-std/src/Script.sol"; contract Setup is Script { function deploySystem( + address owner, address token, address usdc, address stakingRewards, @@ -32,7 +33,7 @@ contract Setup is Script { public returns (KSXVault ksxVault) { - ksxVault = new KSXVault(token, usdc, stakingRewards, auctionFactory, decimalOffset, timeOffset); + ksxVault = new KSXVault(owner, token, usdc, stakingRewards, auctionFactory, decimalOffset, timeOffset); // deploy ERC1967 proxy and set implementation to ksxVault Proxy proxy = new Proxy(address(ksxVault), ""); diff --git a/src/KSXVault.sol b/src/KSXVault.sol index 50b558d..6d8cc89 100644 --- a/src/KSXVault.sol +++ b/src/KSXVault.sol @@ -7,11 +7,12 @@ import {ERC4626} from import {IStakingRewardsV2} from "@token/interfaces/IStakingRewardsV2.sol"; import {AuctionFactory} from "./AuctionFactory.sol"; import {Auction} from "./Auction.sol"; +import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; /// @title KSXVault Contract /// @notice KSX ERC4626 Vault /// @author Flocqst (florian@kwenta.io) -contract KSXVault is ERC4626 { +contract KSXVault is ERC4626, Ownable { /*/////////////////////////////////////////////////////////////// CONSTANTS/IMMUTABLES @@ -20,6 +21,12 @@ contract KSXVault is ERC4626 { /// @notice max amount of days the time can be offset by uint internal constant MAX_OFFSET_DAYS = 6; + /// @notice min auction cooldown + uint internal constant MIN_AUCTION_COOLDOWN = 1 days; + + /// @notice max auction cooldown + uint internal constant MAX_AUCTION_COOLDOWN = 1 weeks; + /// @notice Decimal offset used for calculating the conversion rate between /// KWENTA and KSX. /// @dev Set to 3 to ensure the initial fixed ratio of 1,000 KSX per KWENTA @@ -58,6 +65,9 @@ contract KSXVault is ERC4626 { /// @notice track last time the auction was started uint256 public lastAuctionStartTime; + /// @notice the cooldown period for auctions + uint256 public auctionCooldown; + /// @notice the week offset in seconds uint256 internal immutable timeOffset; @@ -66,6 +76,7 @@ contract KSXVault is ERC4626 { //////////////////////////////////////////////////////////////*/ /// @notice Constructs the KSXVault contract + /// @param _owner The owner of the contract (access to setAuctionCooldown) /// @param _token Kwenta token address /// @param _usdc USDC token address /// @param _stakingRewards Kwenta v2 staking rewards contract @@ -74,6 +85,7 @@ contract KSXVault is ERC4626 { /// underlying asset's decimals and the vault decimals /// @param _daysToOffsetBy the number of days to offset the week by constructor( + address _owner, address _token, address _usdc, address _stakingRewards, @@ -83,6 +95,7 @@ contract KSXVault is ERC4626 { ) ERC4626(IERC20(_token)) ERC20("KSX Vault", "KSX") + Ownable(_owner) { decimalOffset = _decimalOffset; STAKING_REWARDS = IStakingRewardsV2(_stakingRewards); @@ -90,6 +103,8 @@ contract KSXVault is ERC4626 { USDC = IERC20(_usdc); auctionFactory = AuctionFactory(_auctionFactory); + auctionCooldown = MAX_AUCTION_COOLDOWN; + if (_daysToOffsetBy > MAX_OFFSET_DAYS) { revert OffsetTooBig(); } @@ -104,7 +119,7 @@ contract KSXVault is ERC4626 { } /*////////////////////////////////////////////////////////////// - START AUCTION FUNCTIONS + AUCTION FUNCTIONS //////////////////////////////////////////////////////////////*/ /// @notice Starts the auction with the USDC balance of the vault @@ -132,6 +147,11 @@ contract KSXVault is ERC4626 { } + function setAuctionCooldown(uint256 _auctionCooldown) public onlyOwner() { + require(_auctionCooldown >= MIN_AUCTION_COOLDOWN && _auctionCooldown <= MAX_AUCTION_COOLDOWN, "KSXVault: Invalid cooldown"); + auctionCooldown = _auctionCooldown; + } + /// @notice Checks if the auction is ready to start function auctionReady() public view returns (bool) { if (_startOfWeek(block.timestamp) > lastAuctionStartTime) { diff --git a/test/KSXVault.t.sol b/test/KSXVault.t.sol index 1bc8637..bccfb69 100644 --- a/test/KSXVault.t.sol +++ b/test/KSXVault.t.sol @@ -108,6 +108,10 @@ contract KSXVaultTest is Bootstrap { vm.stopPrank(); } +} + +contract KSXVaultAuctionTest is KSXVaultTest { + function test_auctionReady() public { assertEq(ksxVault.auctionReady(), false); assertEq(block.timestamp, 1); diff --git a/test/utils/Bootstrap.sol b/test/utils/Bootstrap.sol index 80287ce..5180190 100644 --- a/test/utils/Bootstrap.sol +++ b/test/utils/Bootstrap.sol @@ -33,7 +33,7 @@ contract Bootstrap is Test, Constants { function initializeLocal(address _token, address _usdc, address _stakingRewards, address _auctionFactory, uint8 _decimalsOffset, uint256 _daysToOffsetBy) internal { BootstrapLocal bootstrap = new BootstrapLocal(); - (address ksxVaultAddress) = bootstrap.init(_token, _usdc, _stakingRewards, _auctionFactory, _decimalsOffset, _daysToOffsetBy); + (address ksxVaultAddress) = bootstrap.init(PDAOADDR, _token, _usdc, _stakingRewards, _auctionFactory, _decimalsOffset, _daysToOffsetBy); decimalsOffset = _decimalsOffset; TOKEN = IERC20(_token); @@ -46,6 +46,7 @@ contract Bootstrap is Test, Constants { contract BootstrapLocal is Setup { function init( + address _owner, address _token, address _usdc, address _stakingRewards, @@ -56,7 +57,7 @@ contract BootstrapLocal is Setup { public returns (address) { - (KSXVault ksxvault) = Setup.deploySystem(_token, _usdc, _stakingRewards, _auctionFactory, _decimalsOffset, _timeOffset); + (KSXVault ksxvault) = Setup.deploySystem(_owner, _token, _usdc, _stakingRewards, _auctionFactory, _decimalsOffset, _timeOffset); return (address(ksxvault)); }