Compare commits
No commits in common. "bc85560b40d98c419efbc203a2d0ad3d9264926d" and "7c9c9f90def71e0854444a43af31e9d35d8f04ca" have entirely different histories.
bc85560b40
...
7c9c9f90de
@ -63,10 +63,6 @@ RESERVE_PROFIT=
|
|||||||
|
|
||||||
INITIAL_INDEX=
|
INITIAL_INDEX=
|
||||||
|
|
||||||
## Network specific native coefficient
|
|
||||||
COEFFICIENT_NUMERATOR=
|
|
||||||
COEFFICIENT_DENOMINATOR=
|
|
||||||
|
|
||||||
## Blocks needed for permissions to take place, only needed if timelock enabled
|
## Blocks needed for permissions to take place, only needed if timelock enabled
|
||||||
BLOCKS_NEEDED_FOR_TREASURY_QUEUE=
|
BLOCKS_NEEDED_FOR_TREASURY_QUEUE=
|
||||||
|
|
||||||
|
|||||||
@ -46,7 +46,6 @@ contract GhostBondingCalculator is IBondingCalculator {
|
|||||||
uint256 totalSupply = IUniswapV2Pair(pair).totalSupply();
|
uint256 totalSupply = IUniswapV2Pair(pair).totalSupply();
|
||||||
|
|
||||||
value = totalValue * FixedPoint.fraction(amount, totalSupply).decode112with18() / 1e18;
|
value = totalValue * FixedPoint.fraction(amount, totalSupply).decode112with18() / 1e18;
|
||||||
value = value * fraction / 1e18;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function markdown(address pair) external view override returns (uint256 reserve) {
|
function markdown(address pair) external view override returns (uint256 reserve) {
|
||||||
|
|||||||
@ -223,39 +223,51 @@ 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);
|
IERC20(weth).approve(router, amount + 1);
|
||||||
|
|
||||||
(uint256 reserve0, uint256 reserve1,) = IUniswapV2Pair(pair).getReserves();
|
(uint256 reserve0, uint256 reserve1,) = IUniswapV2Pair(pair).getReserves();
|
||||||
address[] memory path = new address[](2);
|
address[] memory path;
|
||||||
path[0] = weth;
|
|
||||||
path[1] = ftso;
|
|
||||||
|
|
||||||
if (ftso < weth) {
|
if (ftso < weth) {
|
||||||
|
path[0] = ftso;
|
||||||
|
path[1] = 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[1],
|
amounts[0],
|
||||||
path,
|
path,
|
||||||
address(this),
|
address(this),
|
||||||
block.timestamp
|
block.timestamp
|
||||||
);
|
);
|
||||||
|
|
||||||
amountIn = amount - amountIn;
|
amountIn = amount - amountIn;
|
||||||
|
IERC20(ftso).approve(router, amountIn + 1);
|
||||||
|
|
||||||
IERC20(weth).transfer(pair, amountIn);
|
IUniswapV2Router02(router).addLiquidity(
|
||||||
IERC20(ftso).transfer(pair, amounts[1]);
|
path[0],
|
||||||
IUniswapV2Pair(pair).mint(address(this));
|
path[1],
|
||||||
|
amountIn,
|
||||||
|
amounts[0],
|
||||||
|
amountIn * (1e7 - slippage) / 1e7,
|
||||||
|
amounts[0] * (1e7 - slippage) / 1e7,
|
||||||
|
address(this),
|
||||||
|
block.timestamp
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function indexInRegistry(
|
function indexInRegistry(
|
||||||
|
|||||||
@ -1,74 +0,0 @@
|
|||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue
Block a user