From 28bae5945c079f2a32694c1b1b899131fc573b2c Mon Sep 17 00:00:00 2001 From: owen05 Date: Sun, 19 Dec 2021 12:33:17 +0800 Subject: [PATCH] fix --- contracts/DODOStarter/impl/FairFunding.sol | 40 +++++++-------- contracts/DODOStarter/impl/InstantFunding.sol | 25 +++------ contracts/DODOStarter/impl/Vesting.sol | 51 +++++++++++++------ contracts/Factory/DODOStarterFactory.sol | 6 ++- .../SmartRoute/proxies/DODOStarterProxy.sol | 1 + 5 files changed, 66 insertions(+), 57 deletions(-) diff --git a/contracts/DODOStarter/impl/FairFunding.sol b/contracts/DODOStarter/impl/FairFunding.sol index 457ded9..adbb001 100644 --- a/contracts/DODOStarter/impl/FairFunding.sol +++ b/contracts/DODOStarter/impl/FairFunding.sol @@ -14,13 +14,12 @@ import {DecimalMath} from "../../lib/DecimalMath.sol"; import {IERC20} from "../../intf/IERC20.sol"; import {SafeERC20} from "../../lib/SafeERC20.sol"; import {Vesting} from "./Vesting.sol"; -import {IDVM} from "../../DODOVendingMachine/intf/IDVM.sol"; -import {IDVMFactory} from "../../Factory/DVMFactory.sol"; contract FairFunding is Vesting { using SafeMath for uint256; using SafeERC20 for IERC20; + uint256 internal constant _SETTEL_FUND_ = 200 finney; // ============ Fair Mode ============ uint256 public _COOLING_DURATION_; @@ -32,6 +31,10 @@ contract FairFunding is Vesting { uint256 public _LOWER_LIMIT_PRICE_; uint256 public _UPPER_LIMIT_PRICE_; + receive() external payable { + require(_INITIALIZED_ == false, "WE_NOT_SAVE_ETH_AFTER_INIT"); + } + // ============ Init ============ function init( address[] calldata addressList, @@ -118,6 +121,7 @@ contract FairFunding is Vesting { _TOTAL_TOKEN_AMOUNT_ = IERC20(_TOKEN_ADDRESS_).balanceOf(address(this)); require(_TOTAL_TOKEN_AMOUNT_ > 0, "NO_TOKEN_TRANSFERED"); + require(address(this).balance == _SETTEL_FUND_, "SETTLE_FUND_NOT_MATCH"); } // ============ View Functions ============ @@ -159,7 +163,7 @@ contract FairFunding is Vesting { // ============ Settle Functions ============ - function settle() public isForceStop { + function settle() public isForceStop preventReentrant { require(_FINAL_PRICE_ == 0 && isFundingEnd(), "CAN_NOT_SETTLE"); _FINAL_PRICE_ = getCurrentPrice(); if(_TOTAL_RAISED_FUNDS_ == 0) { @@ -172,6 +176,8 @@ contract FairFunding is Vesting { if (_USED_FUND_RATIO_ > DecimalMath.ONE) { _USED_FUND_RATIO_ = DecimalMath.ONE; } + + msg.sender.transfer(_SETTEL_FUND_); } // ============ Funding Functions ============ @@ -208,39 +214,31 @@ contract FairFunding is Vesting { } function withdrawUnallocatedToken(address to) external preventReentrant onlyOwner { + require(isSettled(), "NOT_SETTLED"); require(_FINAL_PRICE_ == _LOWER_LIMIT_PRICE_, "NO_TOKEN_LEFT"); uint256 allocatedToken = DecimalMath.divCeil(_TOTAL_RAISED_FUNDS_, _FINAL_PRICE_); IERC20(_TOKEN_ADDRESS_).safeTransfer(to, _TOTAL_TOKEN_AMOUNT_.sub(allocatedToken)); _TOTAL_TOKEN_AMOUNT_ = allocatedToken; } - function initializeLiquidity(uint256 initialTokenAmount, uint256 lpFeeRate, bool isOpenTWAP) external preventReentrant onlyOwner { require(isSettled(), "NOT_SETTLED"); - _INITIAL_POOL_ = IDVMFactory(_POOL_FACTORY_).createDODOVendingMachine( - _TOKEN_ADDRESS_, - _FUNDS_ADDRESS_, - lpFeeRate, - 1, - DecimalMath.ONE, - isOpenTWAP - ); - IERC20(_TOKEN_ADDRESS_).transferFrom(msg.sender, _INITIAL_POOL_, initialTokenAmount); - - if(_TOTAL_RAISED_FUNDS_ > _INITIAL_FUND_LIQUIDITY_) { - IERC20(_FUNDS_ADDRESS_).transfer(_INITIAL_POOL_, _INITIAL_FUND_LIQUIDITY_); - }else { - IERC20(_FUNDS_ADDRESS_).transfer(_INITIAL_POOL_, _TOTAL_RAISED_FUNDS_); - } - - (_TOTAL_LP_, , ) = IDVM(_INITIAL_POOL_).buyShares(address(this)); + uint256 totalUsedRaiseFunds = DecimalMath.mulFloor(_TOTAL_RAISED_FUNDS_, _USED_FUND_RATIO_); + _initializeLiquidity(initialTokenAmount, totalUsedRaiseFunds, lpFeeRate, isOpenTWAP); } function claimToken(address to) external { + require(isSettled(), "NOT_SETTLED"); uint256 totalAllocation = getUserTokenAllocation(msg.sender); _claimToken(to, totalAllocation); } + function claimFund(address to) external preventReentrant onlyOwner { + require(isSettled(), "NOT_SETTLED"); + uint256 totalUsedRaiseFunds = DecimalMath.mulFloor(_TOTAL_RAISED_FUNDS_, _USED_FUND_RATIO_); + _claimFunds(to,totalUsedRaiseFunds); + } + // ============ Timeline Control Functions ============ function isDepositOpen() public view returns (bool) { diff --git a/contracts/DODOStarter/impl/InstantFunding.sol b/contracts/DODOStarter/impl/InstantFunding.sol index e9aaa9a..6bea048 100644 --- a/contracts/DODOStarter/impl/InstantFunding.sol +++ b/contracts/DODOStarter/impl/InstantFunding.sol @@ -14,8 +14,7 @@ import {DecimalMath} from "../../lib/DecimalMath.sol"; import {IERC20} from "../../intf/IERC20.sol"; import {SafeERC20} from "../../lib/SafeERC20.sol"; import {Vesting} from "./Vesting.sol"; -import {IDVM} from "../../DODOVendingMachine/intf/IDVM.sol"; -import {IDVMFactory} from "../../Factory/DVMFactory.sol"; + contract InstantFunding is Vesting { using SafeMath for uint256; @@ -198,25 +197,9 @@ contract InstantFunding is Vesting { _TOTAL_TOKEN_AMOUNT_ = _TOTAL_ALLOCATED_TOKEN_; } - function initializeLiquidity(uint256 initialTokenAmount, uint256 lpFeeRate, bool isOpenTWAP) external preventReentrant onlyOwner { require(isFundingEnd(),"FUNDING_NOT_FINISHED"); - _INITIAL_POOL_ = IDVMFactory(_POOL_FACTORY_).createDODOVendingMachine( - _TOKEN_ADDRESS_, - _FUNDS_ADDRESS_, - lpFeeRate, - 1, - DecimalMath.ONE, - isOpenTWAP - ); - IERC20(_TOKEN_ADDRESS_).transferFrom(msg.sender, _INITIAL_POOL_, initialTokenAmount); - if(_TOTAL_RAISED_FUNDS_ > _INITIAL_FUND_LIQUIDITY_) { - IERC20(_FUNDS_ADDRESS_).transfer(_INITIAL_POOL_, _INITIAL_FUND_LIQUIDITY_); - }else { - IERC20(_FUNDS_ADDRESS_).transfer(_INITIAL_POOL_, _TOTAL_RAISED_FUNDS_); - } - - (_TOTAL_LP_, , ) = IDVM(_INITIAL_POOL_).buyShares(address(this)); + _initializeLiquidity(initialTokenAmount, _TOTAL_RAISED_FUNDS_, lpFeeRate, isOpenTWAP); } function claimToken(address to) external { @@ -224,6 +207,10 @@ contract InstantFunding is Vesting { _claimToken(to, totalAllocation); } + function claimFund(address to) external preventReentrant onlyOwner { + _claimFunds(to,_TOTAL_RAISED_FUNDS_); + } + // ============ Timeline Control Functions ============ function isDepositOpen() public view returns (bool) { diff --git a/contracts/DODOStarter/impl/Vesting.sol b/contracts/DODOStarter/impl/Vesting.sol index da2fad0..0394fd6 100644 --- a/contracts/DODOStarter/impl/Vesting.sol +++ b/contracts/DODOStarter/impl/Vesting.sol @@ -13,23 +13,13 @@ import {SafeMath} from "../../lib/SafeMath.sol"; import {DecimalMath} from "../../lib/DecimalMath.sol"; import {IERC20} from "../../intf/IERC20.sol"; import {SafeERC20} from "../../lib/SafeERC20.sol"; +import {IDVM} from "../../DODOVendingMachine/intf/IDVM.sol"; +import {IDVMFactory} from "../../Factory/DVMFactory.sol"; contract Vesting is Storage { using SafeMath for uint256; using SafeERC20 for IERC20; - function claimFunds(address to) external preventReentrant onlyOwner { - require(_TOTAL_RAISED_FUNDS_ > _INITIAL_FUND_LIQUIDITY_, "FUND_NOT_ENOUGH"); - uint256 vestingFunds = _TOTAL_RAISED_FUNDS_.sub(_INITIAL_FUND_LIQUIDITY_); - uint256 remainingFund = DecimalMath.mulFloor( - getRemainingRatio(block.timestamp,1), - vestingFunds - ); - uint256 claimableFund = vestingFunds.sub(remainingFund).sub(_CLAIMED_FUNDS_); - IERC20(_FUNDS_ADDRESS_).safeTransfer(to, claimableFund); - _CLAIMED_FUNDS_ = _CLAIMED_FUNDS_.add(claimableFund); - } - function claimLp(address to) external preventReentrant onlyOwner { require(_INITIAL_POOL_ != address(0), "LIQUIDITY_NOT_ESTABLISHED"); uint256 remainingLp = DecimalMath.mulFloor( @@ -38,11 +28,10 @@ contract Vesting is Storage { ); uint256 claimableLp = _TOTAL_LP_.sub(remainingLp).sub(_CLAIMED_LP_); - IERC20(_INITIAL_POOL_).safeTransfer(to, claimableLp); _CLAIMED_LP_ = _CLAIMED_LP_.add(claimableLp); + IERC20(_INITIAL_POOL_).safeTransfer(to, claimableLp); } - //tokenType 0: BaseToken, 1: Fund, 2: LpToken function getRemainingRatio(uint256 timestamp, uint256 tokenType) public view returns (uint256) { uint256 vestingStart; @@ -78,7 +67,39 @@ contract Vesting is Storage { totalAllocation ); uint256 claimableTokenAmount = totalAllocation.sub(remainingToken).sub(_CLAIMED_TOKEN_[msg.sender]); - IERC20(_TOKEN_ADDRESS_).safeTransfer(to,claimableTokenAmount); _CLAIMED_TOKEN_[msg.sender] = _CLAIMED_TOKEN_[msg.sender].add(claimableTokenAmount); + IERC20(_TOKEN_ADDRESS_).safeTransfer(to,claimableTokenAmount); + } + + function _claimFunds(address to, uint256 totalUsedRaiseFunds) internal { + require(totalUsedRaiseFunds > _INITIAL_FUND_LIQUIDITY_, "FUND_NOT_ENOUGH"); + uint256 vestingFunds = totalUsedRaiseFunds.sub(_INITIAL_FUND_LIQUIDITY_); + uint256 remainingFund = DecimalMath.mulFloor( + getRemainingRatio(block.timestamp,1), + vestingFunds + ); + uint256 claimableFund = vestingFunds.sub(remainingFund).sub(_CLAIMED_FUNDS_); + _CLAIMED_FUNDS_ = _CLAIMED_FUNDS_.add(claimableFund); + IERC20(_FUNDS_ADDRESS_).safeTransfer(to, claimableFund); + } + + function _initializeLiquidity(uint256 initialTokenAmount, uint256 totalUsedRaiseFunds, uint256 lpFeeRate, bool isOpenTWAP) internal { + _INITIAL_POOL_ = IDVMFactory(_POOL_FACTORY_).createDODOVendingMachine( + _TOKEN_ADDRESS_, + _FUNDS_ADDRESS_, + lpFeeRate, + 1, + DecimalMath.ONE, + isOpenTWAP + ); + IERC20(_TOKEN_ADDRESS_).transferFrom(msg.sender, _INITIAL_POOL_, initialTokenAmount); + + if(totalUsedRaiseFunds > _INITIAL_FUND_LIQUIDITY_) { + IERC20(_FUNDS_ADDRESS_).transfer(_INITIAL_POOL_, _INITIAL_FUND_LIQUIDITY_); + }else { + IERC20(_FUNDS_ADDRESS_).transfer(_INITIAL_POOL_, totalUsedRaiseFunds); + } + + (_TOTAL_LP_, , ) = IDVM(_INITIAL_POOL_).buyShares(address(this)); } } diff --git a/contracts/Factory/DODOStarterFactory.sol b/contracts/Factory/DODOStarterFactory.sol index ff01665..bafaa93 100644 --- a/contracts/Factory/DODOStarterFactory.sol +++ b/contracts/Factory/DODOStarterFactory.sol @@ -75,11 +75,13 @@ contract DODOStarterFactory is InitializableOwnable { uint256[] memory timeLine, uint256[] memory valueList, uint256 sellTokenAmount - ) external permissionCheck(addressList[0],addressList[1]) returns(address newFairFundPool){ + ) external payable permissionCheck(addressList[0],addressList[1]) returns(address newFairFundPool){ newFairFundPool = ICloneFactory(_CLONE_FACTORY_).clone(_FAIR_FUND_TEMPLATE_); IERC20(addressList[1]).transferFrom(msg.sender, newFairFundPool,sellTokenAmount); - + (bool success, ) = newFairFundPool.call{value: msg.value}(""); + require(success, "Settle fund Transfer failed"); + IDODOStarter(newFairFundPool).init( addressList, timeLine, diff --git a/contracts/SmartRoute/proxies/DODOStarterProxy.sol b/contracts/SmartRoute/proxies/DODOStarterProxy.sol index 1722ff0..af840da 100644 --- a/contracts/SmartRoute/proxies/DODOStarterProxy.sol +++ b/contracts/SmartRoute/proxies/DODOStarterProxy.sol @@ -71,6 +71,7 @@ contract DODOStarterProxy is ReentrancyGuard { ) internal { if (isETH) { if (amount > 0) { + require(msg.value == amount, "ETH_VALUE_WRONG"); IWETH(_WETH_).deposit{value: amount}(); if (to != address(this)) SafeERC20.safeTransfer(IERC20(_WETH_), to, amount); }