From c1b8654ccc878cb580afe5aa17030d8623528274 Mon Sep 17 00:00:00 2001 From: zhoushuren Date: Sun, 17 Mar 2024 14:09:24 +0800 Subject: [PATCH 1/4] fix bug RewardTracker.sol --- src/staking/RewardTracker.sol | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/staking/RewardTracker.sol b/src/staking/RewardTracker.sol index 6dc8798..42a344b 100644 --- a/src/staking/RewardTracker.sol +++ b/src/staking/RewardTracker.sol @@ -5,7 +5,7 @@ pragma solidity ^0.8.21; import "../interfaces/IRewardDistributor.sol"; import "../interfaces/IRewardTracker.sol"; import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import "forge-std/console.sol"; // test +// import "forge-std/console.sol"; // test contract RewardTracker is IERC20, IRewardTracker { @@ -209,13 +209,12 @@ contract RewardTracker is IERC20, IRewardTracker { totalSupply = totalSupply + _amount; balances[_account] = balances[_account] + _amount; - console.log("_mint:", _account, balances[_account], _amount); + emit Transfer(address(0), _account, _amount); } function _burn(address _account, uint256 _amount) internal { require(_account != address(0), "RewardTracker: burn from the zero address"); - console.log("_burn:", _account, balances[_account] , _amount); balances[_account] = balances[_account] - _amount; totalSupply = totalSupply - _amount; @@ -226,8 +225,11 @@ contract RewardTracker is IERC20, IRewardTracker { require(_sender != address(0), "RewardTracker: transfer from the zero address"); require(_recipient != address(0), "RewardTracker: transfer to the zero address"); + balances[_sender] = balances[_sender] - _amount; - balances[_recipient] = balances[_recipient] = _amount; + // console.log("_transfer: befer", balances[_recipient]); + balances[_recipient] = balances[_recipient] + _amount; + // console.log("_transfer: afet", balances[_recipient]); emit Transfer(_sender, _recipient,_amount); } @@ -308,7 +310,7 @@ contract RewardTracker is IERC20, IRewardTracker { require(stakedAmounts[_account] >= _pointAmount, "RewardTracker: _pointAmount exceeds stakedAmount"); stakedAmounts[_account] = stakedAmount - _pointAmount; - // console.log("_unstake:", totalStakedAmounts, _pointAmount); + totalStakedAmounts = totalStakedAmounts - _pointAmount; uint256 depositBalance = depositBalances[_account][_depositToken]; From f3f71034b5a55976025160c76793e19690665190 Mon Sep 17 00:00:00 2001 From: zhoushuren Date: Wed, 20 Mar 2024 22:45:58 +0800 Subject: [PATCH 2/4] add compound function --- script/DeployFarm.s.sol | 2 +- src/interfaces/IFarm.sol | 2 +- src/peripherals/FarmRouter.sol | 216 ++++++++++++++++---------------- src/peripherals/FarmRouter2.sol | 14 ++- 4 files changed, 119 insertions(+), 115 deletions(-) diff --git a/script/DeployFarm.s.sol b/script/DeployFarm.s.sol index 73f9bfb..19e4054 100644 --- a/script/DeployFarm.s.sol +++ b/script/DeployFarm.s.sol @@ -23,7 +23,7 @@ contract DeployFarm is BaseScript { RewardDistributor rd = new RewardDistributor(UN); // RewardDistributor 全局只需要一个即可 - RewardTracker ulp = new RewardTracker("UNIT warp LP WETH/TINU", "ULP"); + RewardTracker ulp = new RewardTracker("UNIT wrap LP WETH/TINU", "ULP"); UnitPriceFeed priceFeed = new UnitPriceFeed(); // 为ULP创建一个priceFeed uint256 price = 1100000 * 1e18; priceFeed.setLatestAnswer(int256(price)); diff --git a/src/interfaces/IFarm.sol b/src/interfaces/IFarm.sol index ea1edf0..fe4e3bc 100644 --- a/src/interfaces/IFarm.sol +++ b/src/interfaces/IFarm.sol @@ -4,7 +4,7 @@ pragma solidity ^0.8.21; interface IFarm { - function depositETH(uint8 lock) external; + function depositETH(uint8 lock) external payable; function deposit(address _depositToken, uint256 _amount, uint8 _lockDay) external; function withdraw(address _uLP, uint256 _lockIndex, address _receiver) external; } \ No newline at end of file diff --git a/src/peripherals/FarmRouter.sol b/src/peripherals/FarmRouter.sol index 42aa1d3..9c3191b 100644 --- a/src/peripherals/FarmRouter.sol +++ b/src/peripherals/FarmRouter.sol @@ -1,121 +1,121 @@ -// SPDX-License-Identifier: MIT +// // SPDX-License-Identifier: MIT -pragma solidity ^0.8.21; +// pragma solidity ^0.8.21; -import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; -import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import { IUniswapV2Router01 } from "../test/IUniswapV2Router01.sol"; -import { IWETH } from "../interfaces/IWETH.sol"; -import { IFarm } from "../interfaces/IFarm.sol"; -import { IVault } from "../interfaces/IVault.sol"; +// import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; +// import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +// import { IUniswapV2Router01 } from "../test/IUniswapV2Router01.sol"; +// import { IWETH } from "../interfaces/IWETH.sol"; +// import { IFarm } from "../interfaces/IFarm.sol"; +// import { IVault } from "../interfaces/IVault.sol"; -import "forge-std/console.sol"; // test +// import "forge-std/console.sol"; // test -contract FarmRouter is Ownable { +// contract FarmRouter is Ownable { - address public TINU; +// address public TINU; - address public UN; +// address public UN; - address public uniswapRouter; +// address public uniswapRouter; - address public WETH; +// address public WETH; - address public farm; +// address public farm; - address public pair0; +// address public pair0; - address public pair1; - - address public VAULT; - - constructor( - address initialOnwer, - address _tinu, - address _un, - address _WETH , - address _uniswapRouter, - address _farm, - address _pair0, - address _pair1, - address _VAULT - ) Ownable(initialOnwer){ - TINU = _tinu; - UN = _un; - WETH = _WETH; - uniswapRouter = _uniswapRouter; - farm = _farm; - pair0 = _pair0; - pair1 = _pair1; - VAULT = _VAULT; - - setApprove(); - } - - function setApprove() public { - IWETH(WETH).approve(uniswapRouter, type(uint256).max ); - IERC20(TINU).approve(uniswapRouter, type(uint256).max ); - IERC20(UN).approve(uniswapRouter, type(uint256).max ); - } - - function depositETHAndAddLiquidity( - uint256 tinuAmountOut, // mint多少tinu - uint256 ethAmountInMax, // 用多少eth 质押 - uint256[] calldata amountA, // add ETH/TINU 的数量 - uint256 unAmountOut, // 买多少UN - uint256 tinuAmountInMax, // 最多输入多说TINU - uint256[] calldata amountB, // add TINU/UN 的数量 - uint256 _multiplierIndex // 倍数, - ) public payable{ - require(msg.value > 0, "FarmRouter: value cannot be 0"); - IWETH(WETH).deposit{value: msg.value}(); - // uint256 ethBalance = IWETH(WETH).balanceOf(address(this)); - IWETH(WETH).transfer(VAULT, ethAmountInMax); - IVault(VAULT).increaseCollateral(WETH, address(this)); - IVault(VAULT).increaseDebt(WETH, tinuAmountOut , address(this)); - // ( uint256 tokenAssets, uint256 tinuDebt ) = IVault(VAULT).vaultOwnerAccount(address(this), address(WETH)); - // console.log("depositETHAndAddLiquidity", tokenAssets, tinuDebt); - IUniswapV2Router01(uniswapRouter).addLiquidity( - WETH, - TINU, - amountA[0], - amountA[1], - 0, - 0, - address(this), - block.timestamp+1 - ); +// address public pair1; + +// address public VAULT; + +// constructor( +// address initialOnwer, +// address _tinu, +// address _un, +// address _WETH , +// address _uniswapRouter, +// address _farm, +// address _pair0, +// address _pair1, +// address _VAULT +// ) Ownable(initialOnwer){ +// TINU = _tinu; +// UN = _un; +// WETH = _WETH; +// uniswapRouter = _uniswapRouter; +// farm = _farm; +// pair0 = _pair0; +// pair1 = _pair1; +// VAULT = _VAULT; + +// setApprove(); +// } + +// function setApprove() public { +// IWETH(WETH).approve(uniswapRouter, type(uint256).max ); +// IERC20(TINU).approve(uniswapRouter, type(uint256).max ); +// IERC20(UN).approve(uniswapRouter, type(uint256).max ); +// } + +// function depositETHAndAddLiquidity( +// uint256 tinuAmountOut, // mint多少tinu +// uint256 ethAmountInMax, // 用多少eth 质押 +// uint256[] calldata amountA, // add ETH/TINU 的数量 +// uint256 unAmountOut, // 买多少UN +// uint256 tinuAmountInMax, // 最多输入多说TINU +// uint256[] calldata amountB, // add TINU/UN 的数量 +// uint256 _multiplierIndex // 倍数, +// ) public payable{ +// require(msg.value > 0, "FarmRouter: value cannot be 0"); +// IWETH(WETH).deposit{value: msg.value}(); +// // uint256 ethBalance = IWETH(WETH).balanceOf(address(this)); +// IWETH(WETH).transfer(VAULT, ethAmountInMax); +// IVault(VAULT).increaseCollateral(WETH, address(this)); +// IVault(VAULT).increaseDebt(WETH, tinuAmountOut , address(this)); +// // ( uint256 tokenAssets, uint256 tinuDebt ) = IVault(VAULT).vaultOwnerAccount(address(this), address(WETH)); +// // console.log("depositETHAndAddLiquidity", tokenAssets, tinuDebt); +// IUniswapV2Router01(uniswapRouter).addLiquidity( +// WETH, +// TINU, +// amountA[0], +// amountA[1], +// 0, +// 0, +// address(this), +// block.timestamp+1 +// ); - address[] memory path1 = new address[](2); - path1[0] = TINU; - path1[1] = UN; +// address[] memory path1 = new address[](2); +// path1[0] = TINU; +// path1[1] = UN; - IUniswapV2Router01(uniswapRouter).swapTokensForExactTokens( - uint(unAmountOut), - uint(tinuAmountInMax), - path1, - address(this), - block.timestamp+1 - ); - - IUniswapV2Router01(uniswapRouter).addLiquidity( - UN, - TINU, - amountB[0], - amountB[1], - 0, - 0, - address(this), - block.timestamp+1 - ); - - uint256 lp0Amount = IERC20(pair0).balanceOf(address(this)); - uint256 lp1Amount = IERC20(pair1).balanceOf(address(this)); - - IERC20(pair0).approve(address(farm), type(uint256).max ); - IERC20(pair1).approve(address(farm), type(uint256).max ); - - IFarm(farm).depositAndLock(0, _multiplierIndex, lp0Amount, address(msg.sender)); - IFarm(farm).depositAndLock(1, _multiplierIndex, lp1Amount, address((msg.sender))); - } -} +// IUniswapV2Router01(uniswapRouter).swapTokensForExactTokens( +// uint(unAmountOut), +// uint(tinuAmountInMax), +// path1, +// address(this), +// block.timestamp+1 +// ); + +// IUniswapV2Router01(uniswapRouter).addLiquidity( +// UN, +// TINU, +// amountB[0], +// amountB[1], +// 0, +// 0, +// address(this), +// block.timestamp+1 +// ); + +// uint256 lp0Amount = IERC20(pair0).balanceOf(address(this)); +// uint256 lp1Amount = IERC20(pair1).balanceOf(address(this)); + +// IERC20(pair0).approve(address(farm), type(uint256).max ); +// IERC20(pair1).approve(address(farm), type(uint256).max ); + +// IFarm(farm).depositAndLock(0, _multiplierIndex, lp0Amount, address(msg.sender)); +// IFarm(farm).depositAndLock(1, _multiplierIndex, lp1Amount, address((msg.sender))); +// } +// } diff --git a/src/peripherals/FarmRouter2.sol b/src/peripherals/FarmRouter2.sol index aa78e70..8ee1143 100644 --- a/src/peripherals/FarmRouter2.sol +++ b/src/peripherals/FarmRouter2.sol @@ -77,6 +77,13 @@ contract FarmRouter2 is Ownable, IFlashLoan { IERC20(_pair).approve(_ulp, 2**256-1); } + function compound(address _ulp, address _unUlp, address _account, uint8 _lockDay) public { + require( IRewardTracker(_ulp).claimable(_account) > 0, "FarmRouter: claimable cannot be 0"); + IRewardTracker(_ulp).claimForAccount(_account, address(this)); + address _unTinuPair = UniswapV2Library.pairFor(UNISWAP_FACTORY, UN, TINU); + _deposit(_unUlp, UN, _unTinuPair, _lockDay, msg.sender); + } + function depositETH(uint8 lock) public payable { require(msg.value > 0, "FarmRouter: value cannot be 0"); IWETH(WETH).deposit{value: msg.value}(); @@ -93,10 +100,6 @@ contract FarmRouter2 is Ownable, IFlashLoan { _deposit(_uLP, _depositToken, _pair, _lockDay, msg.sender); } - function relock(address _collateralToken, uint256 _lockIndex, uint8 _lockDay) public { - - } - // amount: ulp amount function withdraw(address _uLP, uint256 _lockIndex, address _receiver) public { address _pair = pairs[_uLP]; @@ -130,7 +133,9 @@ contract FarmRouter2 is Ownable, IFlashLoan { address _uLP = uLps[addLP.pair]; IRewardTracker(_uLP).stakeForAccount(address(this), addLP.account, addLP.pair, liquidity, addLP.lockDay); + uint256 balance0 = IERC20(_uLP).balanceOf(VAULT); IERC20(_uLP).transferFrom(addLP.account, VAULT, liquidity); + uint256 balance1 = IERC20(_uLP).balanceOf(VAULT); IVault(VAULT).increaseCollateral(_collateralToken, addLP.account); }else if(fcData.callType == 1) { @@ -158,7 +163,6 @@ contract FarmRouter2 is Ownable, IFlashLoan { IERC20(token0).transfer(_sender, amount0); } - // uint256 tinuBalance2 = IERC20(TINU).balanceOf(address(this)); // (uint256 tokenAssets, uint256 debt) = IVault(VAULT).vaultOwnerAccount(msg.sender, _collateralToken); } From 3aa3e10d9199523bd91ecb2f0bf86fbd6783388d Mon Sep 17 00:00:00 2001 From: zhoushuren Date: Wed, 20 Mar 2024 22:47:06 +0800 Subject: [PATCH 3/4] src/staking/RewardTracker.sol --- src/staking/RewardTracker.sol | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/src/staking/RewardTracker.sol b/src/staking/RewardTracker.sol index 42a344b..653f0b5 100644 --- a/src/staking/RewardTracker.sol +++ b/src/staking/RewardTracker.sol @@ -180,11 +180,9 @@ contract RewardTracker is IERC20, IRewardTracker { if (stakedAmount == 0) { return claimableReward[_account]; } - uint256 supply = totalSupply; + uint256 supply = totalStakedAmounts; uint256 pendingRewards = IRewardDistributor(distributor).pendingRewards(address(this)) * PRECISION; uint256 nextCumulativeRewardPerToken = cumulativeRewardPerToken + (pendingRewards / supply); - // return claimableReward[_account].add( - // stakedAmount.mul(nextCumulativeRewardPerToken.sub(previousCumulatedRewardPerToken[_account])).div(PRECISION)); return claimableReward[_account] + (stakedAmount * (nextCumulativeRewardPerToken - previousCumulatedRewardPerToken[_account]) / PRECISION); } @@ -224,22 +222,15 @@ contract RewardTracker is IERC20, IRewardTracker { function _transfer(address _sender, address _recipient, uint256 _amount) private { require(_sender != address(0), "RewardTracker: transfer from the zero address"); require(_recipient != address(0), "RewardTracker: transfer to the zero address"); - - balances[_sender] = balances[_sender] - _amount; - // console.log("_transfer: befer", balances[_recipient]); balances[_recipient] = balances[_recipient] + _amount; - // console.log("_transfer: afet", balances[_recipient]); - emit Transfer(_sender, _recipient,_amount); } function _approve(address _owner, address _spender, uint256 _amount) private { require(_owner != address(0), "RewardTracker: approve from the zero address"); require(_spender != address(0), "RewardTracker: approve to the zero address"); - allowances[_owner][_spender] = _amount; - emit Approval(_owner, _spender, _amount); } From 9dfbe71b26a57e7c6ff1be9fe7dd8d76f53d0f44 Mon Sep 17 00:00:00 2001 From: zhoushuren Date: Wed, 20 Mar 2024 22:54:07 +0800 Subject: [PATCH 4/4] update compound function --- src/peripherals/FarmRouter2.sol | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/peripherals/FarmRouter2.sol b/src/peripherals/FarmRouter2.sol index 04437f8..5f2a650 100644 --- a/src/peripherals/FarmRouter2.sol +++ b/src/peripherals/FarmRouter2.sol @@ -77,10 +77,11 @@ contract FarmRouter2 is Ownable, IFlashLoan { IERC20(_pair).approve(_ulp, 2**256-1); } - function compound(address _ulp, address _unUlp, address _account, uint8 _lockDay) public { + function compound(address _ulp, address _account, uint8 _lockDay) public { require( IRewardTracker(_ulp).claimable(_account) > 0, "FarmRouter: claimable cannot be 0"); IRewardTracker(_ulp).claimForAccount(_account, address(this)); address _unTinuPair = UniswapV2Library.pairFor(UNISWAP_FACTORY, UN, TINU); + address _unUlp = uLps[_unTinuPair]; _deposit(_unUlp, UN, _unTinuPair, _lockDay, msg.sender); }