use TWAP price from DEX for phantom refunds
Signed-off-by: Uncle Fatso <uncle.fatso@ghostchain.io>
This commit is contained in:
parent
ec29d7e18d
commit
f79b32554d
2
dependencies/uniswap-v2-contracts
vendored
2
dependencies/uniswap-v2-contracts
vendored
@ -1 +1 @@
|
|||||||
Subproject commit 5f4365a3a872a0df3f6026402bba7ac71baa9b33
|
Subproject commit b131a064dbcfe6b2750d0f4c3d576b23c561fdb9
|
||||||
@ -26,7 +26,7 @@ contract Gatekeeper is IGatekeeper, Weaver, ReentrancyGuard {
|
|||||||
uint256 public constant FULL_GAS_RESTORATION_TIME = 3600; // 1 hour
|
uint256 public constant FULL_GAS_RESTORATION_TIME = 3600; // 1 hour
|
||||||
uint256 public constant MAX_ALLOWED_GAS_PRICE = 3e9; // 3 gwei
|
uint256 public constant MAX_ALLOWED_GAS_PRICE = 3e9; // 3 gwei
|
||||||
uint256 public constant PHANTOM_EXPIRY = 432000; // seconds, 5 days
|
uint256 public constant PHANTOM_EXPIRY = 432000; // seconds, 5 days
|
||||||
uint256 public constant GAS_EXECUTION_BUFFER = 21000 + 5969 + 50955;
|
uint256 public constant GAS_EXECUTION_BUFFER = 21000 + 5969 + 67585;
|
||||||
uint256 public constant REGISTRY_INDEX = 0;
|
uint256 public constant REGISTRY_INDEX = 0;
|
||||||
|
|
||||||
address public override staking;
|
address public override staking;
|
||||||
@ -117,6 +117,7 @@ contract Gatekeeper is IGatekeeper, Weaver, ReentrancyGuard {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function ghost(bytes32 receiver, uint256 amount) external override {
|
function ghost(bytes32 receiver, uint256 amount) external override {
|
||||||
|
// TODO: if (!_initialized) revert SomeCoolError();
|
||||||
if (msg.sender != staking) revert NotStaking();
|
if (msg.sender != staking) revert NotStaking();
|
||||||
if (amount < EXISTENTIAL_DEPOSIT) revert NonExistentAmount();
|
if (amount < EXISTENTIAL_DEPOSIT) revert NonExistentAmount();
|
||||||
|
|
||||||
@ -129,6 +130,7 @@ contract Gatekeeper is IGatekeeper, Weaver, ReentrancyGuard {
|
|||||||
uint256 rx,
|
uint256 rx,
|
||||||
uint256 s
|
uint256 s
|
||||||
) external nonReentrant {
|
) external nonReentrant {
|
||||||
|
// TODO: if (!_initialized) revert SomeCoolError();
|
||||||
uint256 gasStart = gasleft();
|
uint256 gasStart = gasleft();
|
||||||
uint256 px = _extractPublicKey(call);
|
uint256 px = _extractPublicKey(call);
|
||||||
|
|
||||||
@ -151,7 +153,7 @@ contract Gatekeeper is IGatekeeper, Weaver, ReentrancyGuard {
|
|||||||
_lastVerificationTime = block.timestamp;
|
_lastVerificationTime = block.timestamp;
|
||||||
|
|
||||||
uint256 gasSpent = (gasStart - gasleft() + GAS_EXECUTION_BUFFER) * currentGasPrice;
|
uint256 gasSpent = (gasStart - gasleft() + GAS_EXECUTION_BUFFER) * currentGasPrice;
|
||||||
try IStaking(staking).phantomRefund(msg.sender, gasSpent, REGISTRY_INDEX, PHANTOM_EXPIRY) {}
|
try IStaking(staking).phantomRefund(msg.sender, gasSpent, PHANTOM_EXPIRY) {}
|
||||||
catch {
|
catch {
|
||||||
emit VoluntaryVerification(msg.sender, gasSpent);
|
emit VoluntaryVerification(msg.sender, gasSpent);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -178,16 +178,17 @@ contract GhostStaking is IStaking, GhostAccessControlled {
|
|||||||
function phantomRefund(
|
function phantomRefund(
|
||||||
address receiver,
|
address receiver,
|
||||||
uint256 amount,
|
uint256 amount,
|
||||||
uint256 registryIndex,
|
|
||||||
uint256 phantomExpiry
|
uint256 phantomExpiry
|
||||||
) external override {
|
) external override {
|
||||||
if (gatekeeper != msg.sender) revert NotGatekeeper();
|
if (gatekeeper != msg.sender) revert NotGatekeeper();
|
||||||
|
|
||||||
|
// forge-lint: disable-next-line(unsafe-typecast)
|
||||||
|
uint96 routerIndex = uint96(dexRouterIndex);
|
||||||
// forge-lint: disable-next-line(unsafe-typecast)
|
// forge-lint: disable-next-line(unsafe-typecast)
|
||||||
uint48 phantomRelease = uint48(block.timestamp + phantomExpiry);
|
uint48 phantomRelease = uint48(block.timestamp + phantomExpiry);
|
||||||
address treasury = ISTNK(stnk).treasury();
|
address treasury = ISTNK(stnk).treasury();
|
||||||
|
|
||||||
ITreasury(treasury).phantomRefund(receiver, phantomRelease, amount, registryIndex);
|
ITreasury(treasury).phantomRefund(receiver, phantomRelease, routerIndex, amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
function recall(address receiver, uint256 amount) external override {
|
function recall(address receiver, uint256 amount) external override {
|
||||||
|
|||||||
@ -88,19 +88,23 @@ contract GhostTreasury is GhostAccessControlled, ITreasury {
|
|||||||
function phantomRefund(
|
function phantomRefund(
|
||||||
address receiver,
|
address receiver,
|
||||||
uint48 phantomRelease,
|
uint48 phantomRelease,
|
||||||
uint256 gasSpent,
|
uint96 dexRouterIndex,
|
||||||
uint256 registryIndex
|
uint256 gasSpent
|
||||||
) external override {
|
) external override {
|
||||||
if (!_permissions[STATUS.STAKING][msg.sender]) revert NotApproved();
|
if (!_permissions[STATUS.STAKING][msg.sender]) revert NotApproved();
|
||||||
|
|
||||||
address reserveToken = _registry[STATUS.RESERVETOKEN].at(registryIndex);
|
address dexRouter = _registry[STATUS.DEXROUTER].at(dexRouterIndex);
|
||||||
if (!_permissions[STATUS.RESERVETOKEN][reserveToken]) revert NotApproved();
|
if (!_permissions[STATUS.DEXROUTER][dexRouter] || dexRouter == address(0)) {
|
||||||
|
revert NotApproved();
|
||||||
|
}
|
||||||
|
|
||||||
uint256 totalSupply = IERC20(FTSO).totalSupply();
|
address wethAddress = IUniswapV2Router01(dexRouter).WETH();
|
||||||
uint256 gasValue = tokenValue(reserveToken, gasSpent);
|
address factory = IUniswapV2Router01(dexRouter).factory();
|
||||||
gasValue = FullMath.mulDiv(gasValue, totalSupply, totalReserves);
|
address pairAddress = IUniswapV2Factory(factory).getPair(FTSO, wethAddress);
|
||||||
|
|
||||||
|
uint256 gasValue = (capturedPriceSnapshots[pairAddress] * gasSpent) >> 112;
|
||||||
uint256 currentExcessReserves = excessReserves();
|
uint256 currentExcessReserves = excessReserves();
|
||||||
|
|
||||||
if (gasValue > 0 && gasValue <= currentExcessReserves) {
|
if (gasValue > 0 && gasValue <= currentExcessReserves) {
|
||||||
IBondDepository(bondDepository).addNote(receiver, gasValue, phantomRelease);
|
IBondDepository(bondDepository).addNote(receiver, gasValue, phantomRelease);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -71,7 +71,7 @@ interface IStaking {
|
|||||||
function ghost(bytes32 receiver, uint256 amount) external;
|
function ghost(bytes32 receiver, uint256 amount) external;
|
||||||
function recall(address receiver, uint256 amount) external;
|
function recall(address receiver, uint256 amount) external;
|
||||||
function recall(uint256 amount, uint256 registryIndex) external returns (address, uint256);
|
function recall(uint256 amount, uint256 registryIndex) external returns (address, uint256);
|
||||||
function phantomRefund(address receiver, uint256 amount, uint256 registryIndex, uint256 phantomExpiry) external;
|
function phantomRefund(address receiver, uint256 amount, uint256 phantomExpiry) external;
|
||||||
function rebase() external returns (uint256);
|
function rebase() external returns (uint256);
|
||||||
|
|
||||||
function index() external view returns (uint256);
|
function index() external view returns (uint256);
|
||||||
|
|||||||
@ -40,7 +40,7 @@ interface ITreasury {
|
|||||||
function registered(STATUS status, address token) external view returns (bool);
|
function registered(STATUS status, address token) external view returns (bool);
|
||||||
function permissioned(STATUS status, address token) external view returns (bool);
|
function permissioned(STATUS status, address token) external view returns (bool);
|
||||||
function registeredAt(STATUS status, uint256 index) external view returns (address);
|
function registeredAt(STATUS status, uint256 index) external view returns (address);
|
||||||
function phantomRefund(address receiver, uint48 phantomExpiry, uint256 gasSpent, uint256 amount) external;
|
function phantomRefund(address receiver, uint48 phantomExpiry, uint96 dexRouterIndex, uint256 gasSpent) external;
|
||||||
function buyBack(address receiver, uint256 amount, uint256 index) external returns (address, uint256);
|
function buyBack(address receiver, uint256 amount, uint256 index) external returns (address, uint256);
|
||||||
function withdraw(address token, uint256 amount) external;
|
function withdraw(address token, uint256 amount) external;
|
||||||
function mint(address _recipient, uint256 _amount) external;
|
function mint(address _recipient, uint256 _amount) external;
|
||||||
|
|||||||
@ -13,6 +13,12 @@ import {WETH9} from "../../src/mocks/WETH9.sol";
|
|||||||
import {GhostBondingCalculator} from "../../src/StandardBondingCalculator.sol";
|
import {GhostBondingCalculator} from "../../src/StandardBondingCalculator.sol";
|
||||||
import {Gatekeeper} from "../../src/Gatekeeper.sol";
|
import {Gatekeeper} from "../../src/Gatekeeper.sol";
|
||||||
import {ITreasury} from "../../src/interfaces/ITreasury.sol";
|
import {ITreasury} from "../../src/interfaces/ITreasury.sol";
|
||||||
|
import {IGatekeeper} from "../../src/interfaces/IGatekeeper.sol";
|
||||||
|
|
||||||
|
import {UniswapV2Router} from "@uniswap-v2-contracts/UniswapV2Router.sol";
|
||||||
|
import {UniswapV2Factory} from "@uniswap-v2-contracts/UniswapV2Factory.sol";
|
||||||
|
|
||||||
|
import {IUniswapV2Pair} from "@uniswap-v2-contracts/interfaces/IUniswapV2Pair.sol";
|
||||||
|
|
||||||
contract GatekeeperRecallTest is Test {
|
contract GatekeeperRecallTest is Test {
|
||||||
uint256 public constant TOTAL_INITIAL_SUPPLY = 5000000000000000;
|
uint256 public constant TOTAL_INITIAL_SUPPLY = 5000000000000000;
|
||||||
@ -50,9 +56,14 @@ contract GatekeeperRecallTest is Test {
|
|||||||
GhostBondDepository bondDepository;
|
GhostBondDepository bondDepository;
|
||||||
WETH9 reserve;
|
WETH9 reserve;
|
||||||
|
|
||||||
|
UniswapV2Factory factory;
|
||||||
|
UniswapV2Router router;
|
||||||
|
|
||||||
function setUp() public {
|
function setUp() public {
|
||||||
vm.startPrank(INITIALIZER, INITIALIZER);
|
vm.startPrank(INITIALIZER, INITIALIZER);
|
||||||
reserve = new WETH9();
|
reserve = new WETH9();
|
||||||
|
factory = new UniswapV2Factory(address(0));
|
||||||
|
router = new UniswapV2Router(address(factory), address(reserve));
|
||||||
authority = new GhostAuthority(
|
authority = new GhostAuthority(
|
||||||
GOVERNOR,
|
GOVERNOR,
|
||||||
GUARDIAN,
|
GUARDIAN,
|
||||||
@ -91,24 +102,77 @@ contract GatekeeperRecallTest is Test {
|
|||||||
treasury.enable(ITreasury.STATUS.RESERVEDEPOSITOR, ALICE, address(0));
|
treasury.enable(ITreasury.STATUS.RESERVEDEPOSITOR, ALICE, address(0));
|
||||||
treasury.enable(ITreasury.STATUS.RESERVETOKEN, address(reserve), address(calculator));
|
treasury.enable(ITreasury.STATUS.RESERVETOKEN, address(reserve), address(calculator));
|
||||||
treasury.enable(ITreasury.STATUS.STAKING, address(staking), address(0));
|
treasury.enable(ITreasury.STATUS.STAKING, address(staking), address(0));
|
||||||
|
treasury.enable(ITreasury.STATUS.DEXROUTER, address(router), address(0));
|
||||||
treasury.setBondDepository(address(bondDepository));
|
treasury.setBondDepository(address(bondDepository));
|
||||||
vm.stopPrank();
|
vm.stopPrank();
|
||||||
|
|
||||||
vm.deal(ALICE, INITIAL_MINT);
|
vm.deal(ALICE, INITIAL_MINT * 2);
|
||||||
|
|
||||||
|
uint256 tokenValue = treasury.tokenValue(address(reserve), INITIAL_MINT / 2);
|
||||||
|
|
||||||
vm.startPrank(ALICE);
|
vm.startPrank(ALICE);
|
||||||
reserve.deposit{value: INITIAL_MINT}();
|
reserve.deposit{value: INITIAL_MINT}();
|
||||||
reserve.approve(address(treasury), type(uint256).max);
|
reserve.approve(address(treasury), type(uint256).max);
|
||||||
treasury.deposit(address(reserve), INITIAL_MINT, treasury.tokenValue(address(reserve), INITIAL_MINT) / 2);
|
treasury.deposit(address(reserve), INITIAL_MINT, tokenValue);
|
||||||
assertEq(ftso.totalSupply(), treasury.baseSupply());
|
assertEq(ftso.totalSupply(), treasury.baseSupply());
|
||||||
vm.stopPrank();
|
vm.stopPrank();
|
||||||
|
|
||||||
|
uint256 ftsoAmount = ftso.balanceOf(ALICE) / 2;
|
||||||
|
uint256 wethAmount = ftsoAmount / 2000;
|
||||||
|
|
||||||
|
vm.startPrank(ALICE);
|
||||||
|
ftso.approve(address(router), ftso.balanceOf(ALICE));
|
||||||
|
router.addLiquidityETH{value: INITIAL_MINT}(
|
||||||
|
address(ftso),
|
||||||
|
ftsoAmount,
|
||||||
|
ftsoAmount,
|
||||||
|
wethAmount,
|
||||||
|
ALICE,
|
||||||
|
1234
|
||||||
|
);
|
||||||
|
vm.stopPrank();
|
||||||
|
|
||||||
|
address pair = factory.getPair(address(reserve), address(ftso));
|
||||||
|
vm.prank(GOVERNOR);
|
||||||
|
treasury.enable(ITreasury.STATUS.LIQUIDITYTOKEN, pair, address(calculator));
|
||||||
|
|
||||||
|
(,, uint48 endBefore,) = staking.epoch();
|
||||||
|
vm.warp(endBefore);
|
||||||
|
vm.roll(block.number + 1);
|
||||||
|
|
||||||
|
IUniswapV2Pair(pair).sync();
|
||||||
|
staking.rebase();
|
||||||
|
assertEq(treasury.cummulativePriceSnapshots(pair), IUniswapV2Pair(pair).price0CumulativeLast());
|
||||||
|
}
|
||||||
|
|
||||||
|
function test_phantomRefundBenchmark() public {
|
||||||
|
vm.startPrank(INITIALIZER);
|
||||||
|
Gatekeeper newGatekeeper = new Gatekeeper(
|
||||||
|
IGatekeeper(staking.gatekeeper()).storageHistory(),
|
||||||
|
address(staking)
|
||||||
|
);
|
||||||
|
vm.stopPrank();
|
||||||
|
|
||||||
|
vm.prank(GOVERNOR);
|
||||||
|
staking.updateGatekeeperAddress(address(newGatekeeper));
|
||||||
|
|
||||||
|
// needed only for GAS_EXECUTION_BUFFER benchmarking with --gas-report flag
|
||||||
|
vm.prank(address(newGatekeeper));
|
||||||
|
staking.phantomRefund(ALICE, 420, 432000);
|
||||||
|
|
||||||
|
vm.prank(address(newGatekeeper));
|
||||||
|
staking.phantomRefund(ALICE, 1337, 432000);
|
||||||
|
|
||||||
|
vm.prank(address(newGatekeeper));
|
||||||
|
staking.phantomRefund(ALICE, 69, 432000);
|
||||||
}
|
}
|
||||||
|
|
||||||
function test_gasPriceCorrectDuringRecall() public {
|
function test_gasPriceCorrectDuringRecall() public {
|
||||||
vm.startPrank(INITIALIZER);
|
address gatekeeperAddress = staking.gatekeeper();
|
||||||
Gatekeeper gatekeeper = Gatekeeper(payable(staking.gatekeeper()));
|
Gatekeeper gatekeeper = Gatekeeper(payable(gatekeeperAddress));
|
||||||
|
|
||||||
|
vm.prank(INITIALIZER);
|
||||||
gatekeeper.updatePublicKeyMetadata(0xb5cd0d028a5e1b6a4eecb113b7e49c8176385eb77c8f134bc1db4bddd7654de6);
|
gatekeeper.updatePublicKeyMetadata(0xb5cd0d028a5e1b6a4eecb113b7e49c8176385eb77c8f134bc1db4bddd7654de6);
|
||||||
vm.stopPrank();
|
|
||||||
|
|
||||||
vm.startPrank(ALICE);
|
vm.startPrank(ALICE);
|
||||||
uint256 aliceBalance = ftso.balanceOf(ALICE);
|
uint256 aliceBalance = ftso.balanceOf(ALICE);
|
||||||
@ -169,10 +233,11 @@ contract GatekeeperRecallTest is Test {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function test_recallChainWorks() public {
|
function test_recallChainWorks() public {
|
||||||
vm.startPrank(INITIALIZER);
|
address gatekeeperAddress = staking.gatekeeper();
|
||||||
Gatekeeper gatekeeper = Gatekeeper(payable(staking.gatekeeper()));
|
Gatekeeper gatekeeper = Gatekeeper(payable(gatekeeperAddress));
|
||||||
|
|
||||||
|
vm.prank(INITIALIZER);
|
||||||
gatekeeper.updatePublicKeyMetadata(0xb5cd0d028a5e1b6a4eecb113b7e49c8176385eb77c8f134bc1db4bddd7654de6);
|
gatekeeper.updatePublicKeyMetadata(0xb5cd0d028a5e1b6a4eecb113b7e49c8176385eb77c8f134bc1db4bddd7654de6);
|
||||||
vm.stopPrank();
|
|
||||||
|
|
||||||
vm.startPrank(ALICE);
|
vm.startPrank(ALICE);
|
||||||
uint256 aliceBalance = ftso.balanceOf(ALICE);
|
uint256 aliceBalance = ftso.balanceOf(ALICE);
|
||||||
|
|||||||
88
test/treasury/TreasuryCumulativePrice.t.soll
Normal file
88
test/treasury/TreasuryCumulativePrice.t.soll
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
pragma solidity 0.8.20;
|
||||||
|
|
||||||
|
import {Test} from "forge-std/Test.sol";
|
||||||
|
|
||||||
|
import {Fatso} from "../../src/FatsoERC20.sol";
|
||||||
|
import {GhostAuthority} from "../../src/GhostAuthority.sol";
|
||||||
|
import {GhostTreasury} from "../../src/Treasury.sol";
|
||||||
|
import {GhostBondingCalculator} from "../../src/StandardBondingCalculator.sol";
|
||||||
|
import {WETH9} from "../../src/mocks/WETH9.sol";
|
||||||
|
|
||||||
|
import {ITreasury} from "../../src/interfaces/ITreasury.sol";
|
||||||
|
import {UniswapV2Pair} from "@uniswap-v2-contracts/UniswapV2Pair.sol";
|
||||||
|
import {UniswapV2Factory} from "@uniswap-v2-contracts/UniswapV2Factory.sol";
|
||||||
|
import {UniswapV2Router} from "@uniswap-v2-contracts/UniswapV2Router.sol";
|
||||||
|
import {IERC20} from "@openzeppelin-contracts/token/ERC20/IERC20.sol";
|
||||||
|
|
||||||
|
// TODO: remove fucking old uniswap dependencies
|
||||||
|
|
||||||
|
contract GhostTreasuryCumulativePriceTest is Test {
|
||||||
|
address public constant OWNER = 0x0000000000000000000000000000000000000001;
|
||||||
|
address public constant GOVERNOR = 0x0000000000000000000000000000000000000002;
|
||||||
|
address public constant GUARDIAN = 0x0000000000000000000000000000000000000003;
|
||||||
|
address public constant ALICE = 0x0000000000000000000000000000000000000004;
|
||||||
|
|
||||||
|
uint256 public constant AMOUNT = 2000 ether;
|
||||||
|
|
||||||
|
Fatso ftso;
|
||||||
|
WETH9 weth;
|
||||||
|
UniswapV2Factory factory;
|
||||||
|
UniswapV2Router router;
|
||||||
|
GhostTreasury treasury;
|
||||||
|
GhostAuthority authority;
|
||||||
|
GhostBondingCalculator calculator;
|
||||||
|
|
||||||
|
function setUp() public {
|
||||||
|
vm.startPrank(OWNER);
|
||||||
|
authority = new GhostAuthority(GOVERNOR, GUARDIAN, OWNER, OWNER);
|
||||||
|
weth = new WETH9();
|
||||||
|
ftso = new Fatso(address(authority), "Fatso", "FTSO");
|
||||||
|
treasury = new GhostTreasury(address(ftso), address(authority));
|
||||||
|
calculator = new GhostBondingCalculator(address(ftso), 2000, 1);
|
||||||
|
factory = new UniswapV2Factory(OWNER);
|
||||||
|
router = new UniswapV2Router(address(factory), address(weth));
|
||||||
|
vm.stopPrank();
|
||||||
|
|
||||||
|
vm.startPrank(GOVERNOR);
|
||||||
|
authority.pushVault(address(treasury));
|
||||||
|
treasury.enable(ITreasury.STATUS.RESERVEDEPOSITOR, ALICE, address(0));
|
||||||
|
treasury.enable(ITreasury.STATUS.RESERVETOKEN, address(weth), address(calculator));
|
||||||
|
treasury.enable(ITreasury.STATUS.DEXROUTER, address(router), address(0));
|
||||||
|
vm.stopPrank();
|
||||||
|
|
||||||
|
vm.deal(ALICE, 4 ether);
|
||||||
|
vm.startPrank(ALICE);
|
||||||
|
weth.deposit{value: 2 ether}();
|
||||||
|
weth.approve(address(treasury), type(uint256).max);
|
||||||
|
treasury.deposit(address(weth), 1 ether, 0);
|
||||||
|
vm.stopPrank();
|
||||||
|
|
||||||
|
vm.startPrank(ALICE);
|
||||||
|
ftso.approve(address(router), type(uint256).max);
|
||||||
|
(,, uint256 liquidity) = router.addLiquidityETH{value: 1 ether}(
|
||||||
|
address(ftso), AMOUNT, AMOUNT, 1 ether, ALICE, 69
|
||||||
|
);
|
||||||
|
vm.stopPrank();
|
||||||
|
|
||||||
|
address lpToken = factory.getPair(address(ftso), address(weth));
|
||||||
|
require(lpToken != address(0), "pair not created");
|
||||||
|
|
||||||
|
vm.startPrank(GOVERNOR);
|
||||||
|
treasury.enable(ITreasury.STATUS.LIQUIDITYTOKEN, lpToken, address(calculator));
|
||||||
|
vm.stopPrank();
|
||||||
|
|
||||||
|
vm.startPrank(ALICE);
|
||||||
|
IERC20(lpToken).approve(address(treasury), type(uint256).max);
|
||||||
|
treasury.deposit(lpToken, liquidity, treasury.tokenValue(lpToken, liquidity));
|
||||||
|
vm.stopPrank();
|
||||||
|
}
|
||||||
|
|
||||||
|
function test_initialTreasuryPricingEmpty() public view {
|
||||||
|
assertEq(treasury.blockTimestampLast(), 0);
|
||||||
|
assertEq(treasury.cummulativePriceLast(), 0);
|
||||||
|
assertEq(treasury.reservesValuationPrice(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: after creation price should be correct but Treasury does not know anything
|
||||||
|
// TODO: change price as hard as possible, and then check the treasury cummulative
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user