// SPDX-License-Identifier: GPL-3.0-or-later pragma solidity ^0.8.19; import "forge-std/Test.sol"; import "forge-std/console.sol"; import {TwabController} from "pt-v5-twab-controller/TwabController.sol"; import "../src/Harberg.sol"; import {TooMuchSnatch, Stake} from "../src/Stake.sol"; import "../src/Sentimenter.sol"; import {ERC1967Proxy} from "@openzeppelin/proxy/ERC1967/ERC1967Proxy.sol"; import {MockSentimenter} from "./mocks/MockSentimenter.sol"; contract SentimenterTest is Test { TwabController tc; Harberg harberg; Stake stake; Sentimenter sentimenter; address liquidityPool; address liquidityManager; address taxPool; function setUp() public { tc = new TwabController(60 * 60, uint32(block.timestamp)); harberg = new Harberg("HARB", "HARB", tc); taxPool = harberg.TAX_POOL(); stake = new Stake(address(harberg)); harberg.setStakingPool(address(stake)); liquidityPool = makeAddr("liquidityPool"); harberg.setLiquidityPool(liquidityPool); liquidityManager = makeAddr("liquidityManager"); harberg.setLiquidityManager(liquidityManager); // deploy upgradeable tuner contract Sentimenter _sentimenter = new Sentimenter(); bytes memory params = abi.encodeWithSignature("initialize(address,address)", address(harberg),address(stake)); ERC1967Proxy proxy = new ERC1967Proxy(address(_sentimenter), params); sentimenter = Sentimenter(address(proxy)); } function doSnatch(address staker, uint256 amount, uint32 taxRate) private returns (uint256 positionId) { vm.startPrank(staker); harberg.approve(address(stake), amount); uint256[] memory empty; positionId = stake.snatch(amount, staker, taxRate, empty); vm.stopPrank(); } function testSentiment() public { uint256 smallstake = 0.3e17; uint256 stakeOneThird = 1 ether; uint256 stakeTwoThird = 2 ether; address staker = makeAddr("staker"); // Mint and distribute tokens vm.startPrank(liquidityManager); // mint all the tokens we will need in the test harberg.mint((smallstake + stakeOneThird + stakeTwoThird) * 5); // send 20% of that to staker harberg.transfer(staker, (smallstake + stakeOneThird + stakeTwoThird) * 2); vm.stopPrank(); // Setup initial stakers uint256 positionId1 = doSnatch(staker, smallstake, 0); uint256 sentiment; sentiment = sentimenter.getSentiment(); // 0.99 - horrible sentiment assertApproxEqRel(sentiment, 9.9e17, 1e16); vm.prank(staker); stake.exitPosition(positionId1); uint256 positionId2 = doSnatch(staker, stakeOneThird, 2); sentiment = sentimenter.getSentiment(); // 0.64 - depressive sentiment assertApproxEqRel(sentiment, 6.4e17, 1e16); vm.prank(staker); stake.exitPosition(positionId2); positionId1 = doSnatch(staker, stakeOneThird, 10); positionId2 = doSnatch(staker, stakeTwoThird, 11); sentiment = sentimenter.getSentiment(); // 0.00018 - feaking good sentiment assertApproxEqRel(sentiment, 1.8e14, 1e17); vm.startPrank(staker); stake.exitPosition(positionId1); stake.exitPosition(positionId2); vm.stopPrank(); positionId1 = doSnatch(staker, stakeOneThird, 29); positionId2 = doSnatch(staker, stakeTwoThird, 29); sentiment = sentimenter.getSentiment(); // 0.024 - pretty good sentiment assertApproxEqRel(sentiment, 2.4e16, 2e16); vm.startPrank(staker); stake.exitPosition(positionId1); stake.exitPosition(positionId2); vm.stopPrank(); positionId2 = doSnatch(staker, stakeTwoThird, 15); sentiment = sentimenter.getSentiment(); // 0.17 - positive sentiment assertApproxEqRel(sentiment, 1.7e17, 2e16); vm.startPrank(staker); stake.exitPosition(positionId2); vm.stopPrank(); positionId1 = doSnatch(staker, stakeOneThird, 15); sentiment = sentimenter.getSentiment(); // 0.4 - OK sentiment assertApproxEqRel(sentiment, 3.9e17, 2e16); } function testContractUpgrade() public { uint256 sentiment = sentimenter.getSentiment(); assertEq(sentiment, 1e18, "should have been upgraded"); address newSent = address(new MockSentimenter()); sentimenter.upgradeTo(newSent); sentiment = sentimenter.getSentiment(); assertEq(sentiment, 0, "should have been upgraded"); } }