Compare commits
No commits in common. "566bf34febb372df9f5c92889d8f0db926103168" and "6a47e18b355fb3089407d1fed312a34eb14b435b" have entirely different histories.
566bf34feb
...
6a47e18b35
@ -251,7 +251,7 @@ contract GhostBondDepository is IBondDepository, NoteKeeper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function isLive(uint256 id) public view override returns (bool) {
|
function isLive(uint256 id) public view override returns (bool) {
|
||||||
return terms[id].conclusion > block.timestamp;
|
return (markets[id].capacity > 0 && terms[id].conclusion > block.timestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
function liveMarkets() external view override returns (uint256[] memory) {
|
function liveMarkets() external view override returns (uint256[] memory) {
|
||||||
|
|||||||
@ -4,7 +4,6 @@ pragma solidity ^0.8.20;
|
|||||||
import {SafeERC20} from "@openzeppelin-contracts/token/ERC20/utils/SafeERC20.sol";
|
import {SafeERC20} from "@openzeppelin-contracts/token/ERC20/utils/SafeERC20.sol";
|
||||||
import {IERC20} from "@openzeppelin-contracts/token/ERC20/IERC20.sol";
|
import {IERC20} from "@openzeppelin-contracts/token/ERC20/IERC20.sol";
|
||||||
|
|
||||||
import {GhostWarmup} from "./Warmup.sol";
|
|
||||||
import {GhostAccessControlled} from "./types/GhostAccessControlled.sol";
|
import {GhostAccessControlled} from "./types/GhostAccessControlled.sol";
|
||||||
|
|
||||||
import {ISTNK} from "./interfaces/ISTNK.sol";
|
import {ISTNK} from "./interfaces/ISTNK.sol";
|
||||||
@ -13,7 +12,6 @@ import {IDistributor} from "./interfaces/IDistributor.sol";
|
|||||||
import {IStaking} from "./interfaces/IStaking.sol";
|
import {IStaking} from "./interfaces/IStaking.sol";
|
||||||
import {IGatekeeper} from "./interfaces/IGatekeeper.sol";
|
import {IGatekeeper} from "./interfaces/IGatekeeper.sol";
|
||||||
import {IGhostAuthority} from "./interfaces/IGhostAuthority.sol";
|
import {IGhostAuthority} from "./interfaces/IGhostAuthority.sol";
|
||||||
import {IGhostWarmup} from "./interfaces/IGhostWarmup.sol";
|
|
||||||
|
|
||||||
contract GhostStaking is IStaking, GhostAccessControlled {
|
contract GhostStaking is IStaking, GhostAccessControlled {
|
||||||
using SafeERC20 for IERC20;
|
using SafeERC20 for IERC20;
|
||||||
@ -29,9 +27,9 @@ contract GhostStaking is IStaking, GhostAccessControlled {
|
|||||||
Epoch public epoch;
|
Epoch public epoch;
|
||||||
address public distributor;
|
address public distributor;
|
||||||
address public gatekeeper;
|
address public gatekeeper;
|
||||||
address public warmup;
|
uint256 public sharesInWarmup;
|
||||||
|
|
||||||
mapping(address => bool) public locks;
|
mapping(address => Claim) public warmupInfo;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
address _ftso,
|
address _ftso,
|
||||||
@ -65,35 +63,40 @@ contract GhostStaking is IStaking, GhostAccessControlled {
|
|||||||
if (isClaim && warmupPeriod == 0) {
|
if (isClaim && warmupPeriod == 0) {
|
||||||
returnAmount = _send(returnAmount, to, isRebase);
|
returnAmount = _send(returnAmount, to, isRebase);
|
||||||
} else {
|
} else {
|
||||||
if (locks[to] && to != msg.sender) revert ExternalDepositsLocked();
|
Claim storage info = warmupInfo[to];
|
||||||
uint48 expiry = epoch.number + warmupPeriod;
|
if (info.lock && to != msg.sender) revert ExternalDepositsLocked();
|
||||||
IGhostWarmup(warmup).addToWarmup(amount, to, expiry);
|
|
||||||
|
info.deposit += returnAmount;
|
||||||
|
info.shares += ISTNK(stnk).sharesForBalance(returnAmount);
|
||||||
|
info.expiry = epoch.number + warmupPeriod;
|
||||||
|
|
||||||
|
sharesInWarmup += ISTNK(stnk).sharesForBalance(returnAmount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function claim(address to, bool isRebase) public override returns (uint256 claimedAmount) {
|
function claim(address to, bool isRebase) public override returns (uint256 claimedAmount) {
|
||||||
if (locks[to] && to != msg.sender) revert ExternalDepositsLocked();
|
Claim memory info = warmupInfo[to];
|
||||||
claimedAmount = IGhostWarmup(warmup).claim(to, epoch.number);
|
if (info.lock && to != msg.sender) revert ExternalDepositsLocked();
|
||||||
if (isRebase) {
|
|
||||||
claimedAmount = IGHST(ghst).balanceFrom(claimedAmount);
|
if (epoch.number >= info.expiry && info.expiry > 0) {
|
||||||
ISTNK(stnk).safeTransfer(to, claimedAmount);
|
delete warmupInfo[to];
|
||||||
} else {
|
sharesInWarmup -= info.shares;
|
||||||
IGHST(ghst).mint(to, claimedAmount);
|
claimedAmount = _send(ISTNK(stnk).balanceForShares(info.shares), to, isRebase);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function breakout(bytes32 receiver, uint256 amount) public override {
|
function forfeit() external override returns (uint256) {
|
||||||
IGhostWarmup(warmup).breakout(msg.sender, amount);
|
Claim memory info = warmupInfo[msg.sender];
|
||||||
IGatekeeper(gatekeeper).ghost(receiver, amount);
|
delete warmupInfo[msg.sender];
|
||||||
}
|
|
||||||
|
|
||||||
function forfeit() external override returns (uint256 deposit) {
|
sharesInWarmup -= info.shares;
|
||||||
deposit = IGhostWarmup(warmup).forfeit(msg.sender);
|
|
||||||
IERC20(ftso).safeTransfer(msg.sender, deposit);
|
IERC20(ftso).safeTransfer(msg.sender, info.deposit);
|
||||||
|
return info.deposit;
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleLock() external override {
|
function toggleLock() external override {
|
||||||
locks[msg.sender] = !locks[msg.sender];
|
warmupInfo[msg.sender].lock = !warmupInfo[msg.sender].lock;
|
||||||
}
|
}
|
||||||
|
|
||||||
function unstake(
|
function unstake(
|
||||||
@ -180,10 +183,6 @@ contract GhostStaking is IStaking, GhostAccessControlled {
|
|||||||
function setWarmupPeriod(uint256 _warmupPeriod) external onlyGovernor {
|
function setWarmupPeriod(uint256 _warmupPeriod) external onlyGovernor {
|
||||||
// forge-lint: disable-next-line(unsafe-typecast)
|
// forge-lint: disable-next-line(unsafe-typecast)
|
||||||
warmupPeriod = uint48(_warmupPeriod);
|
warmupPeriod = uint48(_warmupPeriod);
|
||||||
if (warmup == address(0)) {
|
|
||||||
GhostWarmup newWarmup = new GhostWarmup(ghst);
|
|
||||||
warmup = address(newWarmup);
|
|
||||||
}
|
|
||||||
emit WarmupSet(_warmupPeriod);
|
emit WarmupSet(_warmupPeriod);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -197,10 +196,7 @@ contract GhostStaking is IStaking, GhostAccessControlled {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function supplyInWarmup() public view override returns (uint256) {
|
function supplyInWarmup() public view override returns (uint256) {
|
||||||
if (warmup == address(0)) {
|
return ISTNK(stnk).balanceForShares(sharesInWarmup);
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return IGHST(ghst).balanceFrom(IGhostWarmup(warmup).ghstInWarmup());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function ghostedSupply() public view override returns (uint256 amount) {
|
function ghostedSupply() public view override returns (uint256 amount) {
|
||||||
@ -209,12 +205,6 @@ contract GhostStaking is IStaking, GhostAccessControlled {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function warmupInfo(address who) external view returns (uint256, uint256, uint48, bool) {
|
|
||||||
bool lock = locks[who];
|
|
||||||
(uint256 deposit, uint256 payout, uint48 expiry) = IGhostWarmup(warmup).warmupInfo(who);
|
|
||||||
return (deposit, payout, expiry, lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
function _send(
|
function _send(
|
||||||
uint256 amount,
|
uint256 amount,
|
||||||
address to,
|
address to,
|
||||||
|
|||||||
@ -1,80 +0,0 @@
|
|||||||
// 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 breakout(address who, uint256 payout) external override {
|
|
||||||
if (msg.sender != STAKING) revert NotStakingContract();
|
|
||||||
|
|
||||||
Claim storage info = _warmupInfo[who];
|
|
||||||
uint256 depositReduction = FullMath.mulDiv(info.deposit, payout, info.payout);
|
|
||||||
|
|
||||||
info.deposit -= depositReduction;
|
|
||||||
info.payout -= payout;
|
|
||||||
_ghstInWarmup -= payout;
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,20 +0,0 @@
|
|||||||
// SPDX-License-Identifier: MIT
|
|
||||||
pragma solidity ^0.8.20;
|
|
||||||
|
|
||||||
interface IGhostWarmup {
|
|
||||||
struct Claim {
|
|
||||||
uint256 deposit;
|
|
||||||
uint256 payout;
|
|
||||||
uint48 expiry;
|
|
||||||
}
|
|
||||||
|
|
||||||
error NotStakingContract();
|
|
||||||
error ExternalDepositsLocked();
|
|
||||||
|
|
||||||
function addToWarmup(uint256 payout, address who, uint48 expiry) external;
|
|
||||||
function claim(address who, uint256 epochNumber) external returns (uint256);
|
|
||||||
function breakout(address who, uint256 amount) external;
|
|
||||||
function forfeit(address who) external returns (uint256);
|
|
||||||
function ghstInWarmup() external view returns (uint256);
|
|
||||||
function warmupInfo(address who) external view returns (uint256, uint256, uint48);
|
|
||||||
}
|
|
||||||
@ -21,13 +21,7 @@ interface INoteKeeper {
|
|||||||
uint256[] memory _indexes
|
uint256[] memory _indexes
|
||||||
) external returns (uint256);
|
) external returns (uint256);
|
||||||
|
|
||||||
function forceRedeem(
|
|
||||||
bytes32 _receiver,
|
|
||||||
uint256[] memory _indexes
|
|
||||||
) external returns (uint256);
|
|
||||||
|
|
||||||
function redeemAll(address _user, bool _sendGhst) external returns (uint256);
|
function redeemAll(address _user, bool _sendGhst) external returns (uint256);
|
||||||
function forceRedeemAll(bytes32 _receiver) external returns (uint256);
|
|
||||||
function pushNote(address to, uint256 index) external;
|
function pushNote(address to, uint256 index) external;
|
||||||
function pullNote(address from, uint256 index) external returns (uint256 newIndex_);
|
function pullNote(address from, uint256 index) external returns (uint256 newIndex_);
|
||||||
function indexesFor(address _user) external view returns (uint256[] memory);
|
function indexesFor(address _user) external view returns (uint256[] memory);
|
||||||
|
|||||||
@ -32,7 +32,6 @@ interface IStaking {
|
|||||||
) external returns (uint256);
|
) external returns (uint256);
|
||||||
|
|
||||||
function claim(address _recipient, bool _rebasing) external returns (uint256);
|
function claim(address _recipient, bool _rebasing) external returns (uint256);
|
||||||
function breakout(bytes32 _receiver, uint256 _amount) external;
|
|
||||||
function forfeit() external returns (uint256);
|
function forfeit() external returns (uint256);
|
||||||
function toggleLock() external;
|
function toggleLock() external;
|
||||||
|
|
||||||
|
|||||||
@ -3,12 +3,10 @@ pragma solidity ^0.8.20;
|
|||||||
|
|
||||||
library FullMath {
|
library FullMath {
|
||||||
function fullMul(uint256 x, uint256 y) private pure returns (uint256 l, uint256 h) {
|
function fullMul(uint256 x, uint256 y) private pure returns (uint256 l, uint256 h) {
|
||||||
unchecked {
|
uint256 mm = mulmod(x, y, type(uint256).max);
|
||||||
uint256 mm = mulmod(x, y, type(uint256).max);
|
l = x * y;
|
||||||
l = x * y;
|
h = mm - l;
|
||||||
h = mm - l;
|
if (mm < l) h -= 1;
|
||||||
if (mm < l) h -= 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function fullDiv(
|
function fullDiv(
|
||||||
@ -16,22 +14,20 @@ library FullMath {
|
|||||||
uint256 h,
|
uint256 h,
|
||||||
uint256 d
|
uint256 d
|
||||||
) private pure returns (uint256) {
|
) private pure returns (uint256) {
|
||||||
unchecked {
|
uint256 pow2 = d & (~d + 1);
|
||||||
uint256 pow2 = d & (~d + 1);
|
d /= pow2;
|
||||||
d /= pow2;
|
l /= pow2;
|
||||||
l /= pow2;
|
l += h * ((~pow2 + 1) / pow2 + 1);
|
||||||
l += h * ((~pow2 + 1) / pow2 + 1);
|
uint256 r = 1;
|
||||||
uint256 r = 1;
|
r *= 2 - d * r;
|
||||||
r *= 2 - d * r;
|
r *= 2 - d * r;
|
||||||
r *= 2 - d * r;
|
r *= 2 - d * r;
|
||||||
r *= 2 - d * r;
|
r *= 2 - d * r;
|
||||||
r *= 2 - d * r;
|
r *= 2 - d * r;
|
||||||
r *= 2 - d * r;
|
r *= 2 - d * r;
|
||||||
r *= 2 - d * r;
|
r *= 2 - d * r;
|
||||||
r *= 2 - d * r;
|
r *= 2 - d * r;
|
||||||
r *= 2 - d * r;
|
return l * r;
|
||||||
return l * r;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function mulDiv(
|
function mulDiv(
|
||||||
@ -39,19 +35,15 @@ library FullMath {
|
|||||||
uint256 y,
|
uint256 y,
|
||||||
uint256 d
|
uint256 d
|
||||||
) internal pure returns (uint256) {
|
) internal pure returns (uint256) {
|
||||||
if (d == 0) revert("FullMath: DIVISION_BY_ZERO");
|
(uint256 l, uint256 h) = fullMul(x, y);
|
||||||
|
|
||||||
unchecked {
|
uint256 mm = mulmod(x, y, d);
|
||||||
(uint256 l, uint256 h) = fullMul(x, y);
|
if (mm > l) h -= 1;
|
||||||
uint256 mm = mulmod(x, y, d);
|
l -= mm;
|
||||||
|
|
||||||
if (mm > l) h -= 1;
|
if (h == 0) return l / d;
|
||||||
l -= mm;
|
|
||||||
|
|
||||||
if (h == 0) return l / d;
|
require(h < d, "FullMath: FULLDIV_OVERFLOW");
|
||||||
|
return fullDiv(l, h, d);
|
||||||
require(h < d, "FullMath: FULLDIV_OVERFLOW");
|
|
||||||
return fullDiv(l, h, d);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -93,27 +93,6 @@ abstract contract NoteKeeper is INoteKeeper, FrontEndRewarder {
|
|||||||
else _STAKING.unwrap(user, payout);
|
else _STAKING.unwrap(user, payout);
|
||||||
}
|
}
|
||||||
|
|
||||||
function forceRedeem(
|
|
||||||
bytes32 receiver,
|
|
||||||
uint256[] memory indexes
|
|
||||||
) public override returns (uint256 payout) {
|
|
||||||
address user = msg.sender;
|
|
||||||
uint48 time = uint48(block.timestamp);
|
|
||||||
uint256 i;
|
|
||||||
|
|
||||||
for (; i < indexes.length; ) {
|
|
||||||
(uint256 pay, bool matured) = pendingFor(user, indexes[i]);
|
|
||||||
if (matured) {
|
|
||||||
_pendingIndexes[user].remove(indexes[i]);
|
|
||||||
notes[user][indexes[i]].redeemed = time;
|
|
||||||
payout += pay;
|
|
||||||
}
|
|
||||||
unchecked { ++i; }
|
|
||||||
}
|
|
||||||
|
|
||||||
_STAKING.breakout(receiver, payout);
|
|
||||||
}
|
|
||||||
|
|
||||||
function redeemAll(
|
function redeemAll(
|
||||||
address user,
|
address user,
|
||||||
bool sendGhst
|
bool sendGhst
|
||||||
@ -121,10 +100,6 @@ abstract contract NoteKeeper is INoteKeeper, FrontEndRewarder {
|
|||||||
return redeem(user, sendGhst, indexesFor(user));
|
return redeem(user, sendGhst, indexesFor(user));
|
||||||
}
|
}
|
||||||
|
|
||||||
function forceRedeemAll(bytes32 receiver) external override returns (uint256) {
|
|
||||||
return forceRedeem(receiver, indexesFor(msg.sender));
|
|
||||||
}
|
|
||||||
|
|
||||||
function pushNote(address to, uint256 index) external override {
|
function pushNote(address to, uint256 index) external override {
|
||||||
if (notes[msg.sender][index].created == 0) revert NoteNotFound(msg.sender, index);
|
if (notes[msg.sender][index].created == 0) revert NoteNotFound(msg.sender, index);
|
||||||
_noteTransfers[msg.sender][index] = to;
|
_noteTransfers[msg.sender][index] = to;
|
||||||
|
|||||||
@ -89,10 +89,6 @@ contract GhostBondDepositoryTest is Test {
|
|||||||
address(weth)
|
address(weth)
|
||||||
);
|
);
|
||||||
vm.stopPrank();
|
vm.stopPrank();
|
||||||
|
|
||||||
vm.prank(GOVERNOR);
|
|
||||||
staking.setWarmupPeriod(0);
|
|
||||||
|
|
||||||
_createFirstBond();
|
_createFirstBond();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -76,9 +76,6 @@ contract StakingTest is Test {
|
|||||||
gatekeeper = new Gatekeeper(address(staking), 0, 0, 0, 0, 0);
|
gatekeeper = new Gatekeeper(address(staking), 0, 0, 0, 0, 0);
|
||||||
calculator = new GhostBondingCalculator(address(ftso), 1, 1);
|
calculator = new GhostBondingCalculator(address(ftso), 1, 1);
|
||||||
vm.stopPrank();
|
vm.stopPrank();
|
||||||
|
|
||||||
vm.prank(GOVERNOR);
|
|
||||||
staking.setWarmupPeriod(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function test_correctAfterConstruction() public view {
|
function test_correctAfterConstruction() public view {
|
||||||
@ -142,12 +139,13 @@ contract StakingTest is Test {
|
|||||||
|
|
||||||
vm.prank(ALICE);
|
vm.prank(ALICE);
|
||||||
uint256 rebased = staking.stake(AMOUNT, ALICE, false, false);
|
uint256 rebased = staking.stake(AMOUNT, ALICE, false, false);
|
||||||
assertEq(ftso.balanceOf(ALICE), 0);
|
|
||||||
assertApproxEqAbs(staking.supplyInWarmup(), rebased, 1);
|
|
||||||
|
|
||||||
(uint256 deposit, uint256 payout, uint48 expiry, bool lock) = staking.warmupInfo(ALICE);
|
assertEq(ftso.balanceOf(ALICE), 0);
|
||||||
|
assertEq(staking.sharesInWarmup(), stnk.sharesForBalance(rebased));
|
||||||
|
|
||||||
|
(uint256 deposit, uint256 shares, uint48 expiry, bool lock) = staking.warmupInfo(ALICE);
|
||||||
assertEq(deposit, AMOUNT);
|
assertEq(deposit, AMOUNT);
|
||||||
assertEq(payout, ghst.balanceTo(AMOUNT));
|
assertEq(shares, stnk.sharesForBalance(AMOUNT));
|
||||||
assertEq(expiry, 1);
|
assertEq(expiry, 1);
|
||||||
assertEq(lock, false);
|
assertEq(lock, false);
|
||||||
}
|
}
|
||||||
@ -181,11 +179,11 @@ contract StakingTest is Test {
|
|||||||
uint256 rebased = staking.stake(AMOUNT, ALICE, false, true);
|
uint256 rebased = staking.stake(AMOUNT, ALICE, false, true);
|
||||||
|
|
||||||
assertEq(ftso.balanceOf(ALICE), 0);
|
assertEq(ftso.balanceOf(ALICE), 0);
|
||||||
assertApproxEqAbs(staking.supplyInWarmup(), rebased, 1);
|
assertEq(staking.sharesInWarmup(), stnk.sharesForBalance(rebased));
|
||||||
|
|
||||||
(uint256 deposit, uint256 payout, uint48 expiry, bool lock) = staking.warmupInfo(ALICE);
|
(uint256 deposit, uint256 shares, uint48 expiry, bool lock) = staking.warmupInfo(ALICE);
|
||||||
assertEq(deposit, AMOUNT);
|
assertEq(deposit, AMOUNT);
|
||||||
assertEq(payout, ghst.balanceTo(AMOUNT));
|
assertEq(shares, stnk.sharesForBalance(AMOUNT));
|
||||||
assertEq(expiry, 2);
|
assertEq(expiry, 2);
|
||||||
assertEq(lock, false);
|
assertEq(lock, false);
|
||||||
}
|
}
|
||||||
@ -250,7 +248,6 @@ contract StakingTest is Test {
|
|||||||
assertEq(ghst.balanceOf(ALICE), 0);
|
assertEq(ghst.balanceOf(ALICE), 0);
|
||||||
vm.prank(BOB);
|
vm.prank(BOB);
|
||||||
uint256 rebased = staking.claim(ALICE, false);
|
uint256 rebased = staking.claim(ALICE, false);
|
||||||
|
|
||||||
assertEq(ghst.balanceOf(ALICE), rebased);
|
assertEq(ghst.balanceOf(ALICE), rebased);
|
||||||
assertEq(rebased > 0, true);
|
assertEq(rebased > 0, true);
|
||||||
}
|
}
|
||||||
@ -281,11 +278,13 @@ contract StakingTest is Test {
|
|||||||
_prepareAndRoll(ALICE, AMOUNT, false, false);
|
_prepareAndRoll(ALICE, AMOUNT, false, false);
|
||||||
|
|
||||||
assertEq(ftso.balanceOf(ALICE), 0);
|
assertEq(ftso.balanceOf(ALICE), 0);
|
||||||
|
assertEq(staking.sharesInWarmup(), stnk.sharesForBalance(AMOUNT));
|
||||||
|
|
||||||
vm.prank(ALICE);
|
vm.prank(ALICE);
|
||||||
uint256 deposit = staking.forfeit();
|
uint256 deposit = staking.forfeit();
|
||||||
|
|
||||||
assertEq(ftso.balanceOf(ALICE), deposit);
|
assertEq(ftso.balanceOf(ALICE), deposit);
|
||||||
assertEq(staking.supplyInWarmup(), 0);
|
assertEq(staking.sharesInWarmup(), 0);
|
||||||
|
|
||||||
(uint256 depositInWarmup, uint256 shares, uint48 expiry,) = staking.warmupInfo(ALICE);
|
(uint256 depositInWarmup, uint256 shares, uint48 expiry,) = staking.warmupInfo(ALICE);
|
||||||
assertEq(depositInWarmup, 0);
|
assertEq(depositInWarmup, 0);
|
||||||
@ -298,7 +297,7 @@ contract StakingTest is Test {
|
|||||||
uint256 deposit = staking.forfeit();
|
uint256 deposit = staking.forfeit();
|
||||||
assertEq(deposit, 0);
|
assertEq(deposit, 0);
|
||||||
assertEq(ftso.balanceOf(ALICE), 0);
|
assertEq(ftso.balanceOf(ALICE), 0);
|
||||||
assertEq(staking.supplyInWarmup(), 0);
|
assertEq(staking.sharesInWarmup(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
function test_unstake_canRedeemStinkyToFatso() public {
|
function test_unstake_canRedeemStinkyToFatso() public {
|
||||||
|
|||||||
@ -150,7 +150,7 @@ contract StinkyTest is Test, ERC20PermitTest, ERC20AllowanceTest, ERC20TransferT
|
|||||||
staking.stake(AMOUNT, ALICE, true, true);
|
staking.stake(AMOUNT, ALICE, true, true);
|
||||||
vm.stopPrank();
|
vm.stopPrank();
|
||||||
|
|
||||||
assertApproxEqAbs(stnk.circulatingSupply(), AMOUNT, 1);
|
assertEq(stnk.circulatingSupply(), AMOUNT);
|
||||||
assertEq(ftso.totalSupply(), AMOUNT);
|
assertEq(ftso.totalSupply(), AMOUNT);
|
||||||
assertEq(stnk.totalSupply(), TOTAL_INITIAL_SUPPLY);
|
assertEq(stnk.totalSupply(), TOTAL_INITIAL_SUPPLY);
|
||||||
assertEq(stnk.balanceOf(address(staking)), TOTAL_INITIAL_SUPPLY);
|
assertEq(stnk.balanceOf(address(staking)), TOTAL_INITIAL_SUPPLY);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user