ghost-dao-contracts/src/Warmup.sol
Uncle Fatso 17e82c809c
FIX: make breakout and partial claim automatically
Signed-off-by: Uncle Fatso <uncle.fatso@ghostchain.io>
2026-05-11 16:04:39 +03:00

111 lines
3.1 KiB
Solidity

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {IGhostWarmup} from "./interfaces/IGhostWarmup.sol";
import {IGHST} from "./interfaces/IGHST.sol";
import {FullMath} from "./libraries/FullMath.sol";
contract GhostWarmup is IGhostWarmup {
address public immutable STAKING;
address public immutable GHST;
uint256 private _ghstInWarmup;
mapping(address => Claim) private _warmupInfo;
constructor(address ghst) {
STAKING = msg.sender;
GHST = ghst;
}
function addToWarmup(
uint256 payout,
address who,
uint48 expiry
) external override {
if (msg.sender != STAKING) revert NotStakingContract();
Claim storage info = _warmupInfo[who];
uint256 ghstPayout = IGHST(GHST).balanceTo(payout);
info.deposit += payout;
info.payout += ghstPayout;
info.expiry = expiry;
_ghstInWarmup += ghstPayout;
}
function claim(
address to,
uint256 epochNumber
) external override returns (uint256 claimedAmount) {
if (msg.sender != STAKING) revert NotStakingContract();
Claim memory info = _warmupInfo[to];
if (epochNumber >= info.expiry && info.expiry > 0) {
delete _warmupInfo[to];
_ghstInWarmup -= info.payout;
claimedAmount = info.payout;
}
}
function claimByAmount(
address who,
uint256 payout,
uint256 epochNumber
) external override returns (uint256) {
if (msg.sender != STAKING) revert NotStakingContract();
return _reduceWarmupInfo(who, payout, epochNumber);
}
function breakout(
address who,
uint256 payout
) external override returns (uint256) {
if (msg.sender != STAKING) revert NotStakingContract();
return _reduceWarmupInfo(who, payout, type(uint256).max);
}
function forfeit(address who) external override returns (uint256) {
if (msg.sender != STAKING) revert NotStakingContract();
Claim memory info = _warmupInfo[who];
delete _warmupInfo[who];
_ghstInWarmup -= info.payout;
return info.deposit;
}
function ghstInWarmup() external view override returns (uint256) {
return _ghstInWarmup;
}
function warmupInfo(address who) external view override returns (uint256, uint256, uint48) {
Claim memory info = _warmupInfo[who];
return (info.deposit, info.payout, info.expiry);
}
function _reduceWarmupInfo(
address who,
uint256 amount,
uint256 epochNumber
) private returns (uint256) {
Claim storage info = _warmupInfo[who];
if (epochNumber >= info.expiry && info.expiry > 0) {
uint256 mm = mulmod(info.deposit, amount, info.payout);
uint256 depositReduction = FullMath.mulDiv(info.deposit, amount, info.payout);
if (mm > 0) depositReduction += 1;
info.deposit -= depositReduction;
info.payout -= amount;
_ghstInWarmup -= amount;
if (info.payout == 0) delete _warmupInfo[who];
return amount;
}
revert LockedInWarmupPeriod();
}
}