redemtion functionality finalized; mainnet tests added

Signed-off-by: Uncle Fatso <uncle.fatso@ghostchain.io>
This commit is contained in:
Uncle Fatso 2025-10-09 12:48:53 +03:00
parent 6da828cea8
commit 2ab8bc312d
Signed by: f4ts0
GPG Key ID: 565F4F2860226EBB
2 changed files with 84 additions and 22 deletions

View File

@ -223,51 +223,39 @@ contract GhostTreasury is GhostAccessControlled, ITreasury {
function redeemReserve( function redeemReserve(
address router, // could be an issue address router, // could be an issue
uint256 amount, uint256 amount
uint256 slippage
) external onlyGovernor { ) external onlyGovernor {
address weth = IUniswapV2Router01(router).WETH(); address weth = IUniswapV2Router01(router).WETH();
address pair = IUniswapV2Factory(IUniswapV2Router01(router).factory()).getPair(ftso, weth); address pair = IUniswapV2Factory(IUniswapV2Router01(router).factory()).getPair(ftso, weth);
IERC20(weth).approve(router, amount + 1); IERC20(weth).approve(router, amount);
(uint256 reserve0, uint256 reserve1,) = IUniswapV2Pair(pair).getReserves(); (uint256 reserve0, uint256 reserve1,) = IUniswapV2Pair(pair).getReserves();
address[] memory path; address[] memory path = new address[](2);
if (ftso < weth) { path[0] = weth;
path[0] = ftso; path[1] = ftso;
path[1] = weth;
if (ftso < weth) {
reserve0 = reserve1 ^ reserve0; reserve0 = reserve1 ^ reserve0;
reserve1 = reserve1 ^ reserve0; reserve1 = reserve1 ^ reserve0;
reserve0 = reserve1 ^ reserve0; reserve0 = reserve1 ^ reserve0;
} else {
path[0] = weth;
path[1] = ftso;
} }
uint256 amountIn = _quantityToBeSwapped(amount, reserve0); uint256 amountIn = _quantityToBeSwapped(amount, reserve0);
uint256[] memory amounts = IUniswapV2Router02(router).getAmountsOut(amountIn, path); uint256[] memory amounts = IUniswapV2Router02(router).getAmountsOut(amountIn, path);
IUniswapV2Router02(router).swapExactTokensForTokens( IUniswapV2Router02(router).swapExactTokensForTokens(
amountIn, amountIn,
amounts[0], amounts[1],
path, path,
address(this), address(this),
block.timestamp block.timestamp
); );
amountIn = amount - amountIn; amountIn = amount - amountIn;
IERC20(ftso).approve(router, amountIn + 1);
IUniswapV2Router02(router).addLiquidity( IERC20(weth).transfer(pair, amountIn);
path[0], IERC20(ftso).transfer(pair, amounts[1]);
path[1], IUniswapV2Pair(pair).mint(address(this));
amountIn,
amounts[0],
amountIn * (1e7 - slippage) / 1e7,
amounts[0] * (1e7 - slippage) / 1e7,
address(this),
block.timestamp
);
} }
function indexInRegistry( function indexInRegistry(

View File

@ -0,0 +1,74 @@
pragma solidity 0.8.20;
import {Test} from "forge-std/Test.sol";
import {StdChains} from "forge-std/StdChains.sol";
import "../../src/GhostAuthority.sol";
import "../../src/Treasury.sol";
import "../../src/StandardBondingCalculator.sol";
import "@uniswap-v2-periphery-1.1.0-beta.0/interfaces/IWETH.sol";
contract GhostTreasuryRedemptionTest is Test {
address public constant owner = 0x0000000000000000000000000000000000000001;
address public constant governor = 0x0000000000000000000000000000000000000002;
address public constant guardian = 0x0000000000000000000000000000000000000003;
uint256 public constant amount = 69 * 1e18;
address public constant usdc = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48;
address public constant pair = 0xB4e16d0168e52d35CaCD2c6185b44281Ec28C9Dc;
address public constant router = 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D;
address public constant weth = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
GhostTreasury treasury;
GhostAuthority authority;
GhostBondingCalculator calculator;
function setUp() public {
vm.startPrank(owner);
authority = new GhostAuthority(
governor,
guardian,
owner,
owner
);
treasury = new GhostTreasury(usdc, 69, address(authority));
calculator = new GhostBondingCalculator(usdc, 4000, 1);
vm.stopPrank();
vm.startPrank(governor);
treasury.enable(ITreasury.STATUS.RESERVETOKEN, weth, address(calculator));
treasury.enable(ITreasury.STATUS.LIQUIDITYTOKEN, pair, address(calculator));
vm.stopPrank();
}
function test_mainnet_redemptionWorksCorrectly() public {
vm.deal(owner, amount);
vm.startPrank(owner);
IWETH(weth).deposit{value: amount}();
IERC20(weth).transfer(address(treasury), amount);
assertEq(IERC20(weth).balanceOf(address(treasury)), amount);
vm.stopPrank();
assertEq(treasury.totalReserves(), 0);
vm.prank(governor);
treasury.auditReserves();
uint256 prevTotalReserves = treasury.totalReserves();
assertEq(prevTotalReserves > 0, true);
assertEq(IERC20(pair).balanceOf(address(treasury)), 0);
assertEq(IERC20(pair).balanceOf(address(treasury)), 0);
vm.prank(governor);
treasury.redeemReserve(router, amount);
assertEq(IERC20(usdc).balanceOf(address(treasury)), 0);
assertEq(IERC20(weth).balanceOf(address(treasury)), 0);
assertEq(IERC20(pair).balanceOf(address(treasury)) > 0, true);
vm.prank(governor);
treasury.auditReserves();
assertEq(treasury.totalReserves() > prevTotalReserves, true);
}
}