fix
This commit is contained in:
@@ -14,13 +14,12 @@ import {DecimalMath} from "../../lib/DecimalMath.sol";
|
|||||||
import {IERC20} from "../../intf/IERC20.sol";
|
import {IERC20} from "../../intf/IERC20.sol";
|
||||||
import {SafeERC20} from "../../lib/SafeERC20.sol";
|
import {SafeERC20} from "../../lib/SafeERC20.sol";
|
||||||
import {Vesting} from "./Vesting.sol";
|
import {Vesting} from "./Vesting.sol";
|
||||||
import {IDVM} from "../../DODOVendingMachine/intf/IDVM.sol";
|
|
||||||
import {IDVMFactory} from "../../Factory/DVMFactory.sol";
|
|
||||||
|
|
||||||
contract FairFunding is Vesting {
|
contract FairFunding is Vesting {
|
||||||
using SafeMath for uint256;
|
using SafeMath for uint256;
|
||||||
using SafeERC20 for IERC20;
|
using SafeERC20 for IERC20;
|
||||||
|
|
||||||
|
uint256 internal constant _SETTEL_FUND_ = 200 finney;
|
||||||
// ============ Fair Mode ============
|
// ============ Fair Mode ============
|
||||||
uint256 public _COOLING_DURATION_;
|
uint256 public _COOLING_DURATION_;
|
||||||
|
|
||||||
@@ -32,6 +31,10 @@ contract FairFunding is Vesting {
|
|||||||
uint256 public _LOWER_LIMIT_PRICE_;
|
uint256 public _LOWER_LIMIT_PRICE_;
|
||||||
uint256 public _UPPER_LIMIT_PRICE_;
|
uint256 public _UPPER_LIMIT_PRICE_;
|
||||||
|
|
||||||
|
receive() external payable {
|
||||||
|
require(_INITIALIZED_ == false, "WE_NOT_SAVE_ETH_AFTER_INIT");
|
||||||
|
}
|
||||||
|
|
||||||
// ============ Init ============
|
// ============ Init ============
|
||||||
function init(
|
function init(
|
||||||
address[] calldata addressList,
|
address[] calldata addressList,
|
||||||
@@ -118,6 +121,7 @@ contract FairFunding is Vesting {
|
|||||||
_TOTAL_TOKEN_AMOUNT_ = IERC20(_TOKEN_ADDRESS_).balanceOf(address(this));
|
_TOTAL_TOKEN_AMOUNT_ = IERC20(_TOKEN_ADDRESS_).balanceOf(address(this));
|
||||||
|
|
||||||
require(_TOTAL_TOKEN_AMOUNT_ > 0, "NO_TOKEN_TRANSFERED");
|
require(_TOTAL_TOKEN_AMOUNT_ > 0, "NO_TOKEN_TRANSFERED");
|
||||||
|
require(address(this).balance == _SETTEL_FUND_, "SETTLE_FUND_NOT_MATCH");
|
||||||
}
|
}
|
||||||
|
|
||||||
// ============ View Functions ============
|
// ============ View Functions ============
|
||||||
@@ -159,7 +163,7 @@ contract FairFunding is Vesting {
|
|||||||
|
|
||||||
// ============ Settle Functions ============
|
// ============ Settle Functions ============
|
||||||
|
|
||||||
function settle() public isForceStop {
|
function settle() public isForceStop preventReentrant {
|
||||||
require(_FINAL_PRICE_ == 0 && isFundingEnd(), "CAN_NOT_SETTLE");
|
require(_FINAL_PRICE_ == 0 && isFundingEnd(), "CAN_NOT_SETTLE");
|
||||||
_FINAL_PRICE_ = getCurrentPrice();
|
_FINAL_PRICE_ = getCurrentPrice();
|
||||||
if(_TOTAL_RAISED_FUNDS_ == 0) {
|
if(_TOTAL_RAISED_FUNDS_ == 0) {
|
||||||
@@ -172,6 +176,8 @@ contract FairFunding is Vesting {
|
|||||||
if (_USED_FUND_RATIO_ > DecimalMath.ONE) {
|
if (_USED_FUND_RATIO_ > DecimalMath.ONE) {
|
||||||
_USED_FUND_RATIO_ = DecimalMath.ONE;
|
_USED_FUND_RATIO_ = DecimalMath.ONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
msg.sender.transfer(_SETTEL_FUND_);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ============ Funding Functions ============
|
// ============ Funding Functions ============
|
||||||
@@ -208,39 +214,31 @@ contract FairFunding is Vesting {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function withdrawUnallocatedToken(address to) external preventReentrant onlyOwner {
|
function withdrawUnallocatedToken(address to) external preventReentrant onlyOwner {
|
||||||
|
require(isSettled(), "NOT_SETTLED");
|
||||||
require(_FINAL_PRICE_ == _LOWER_LIMIT_PRICE_, "NO_TOKEN_LEFT");
|
require(_FINAL_PRICE_ == _LOWER_LIMIT_PRICE_, "NO_TOKEN_LEFT");
|
||||||
uint256 allocatedToken = DecimalMath.divCeil(_TOTAL_RAISED_FUNDS_, _FINAL_PRICE_);
|
uint256 allocatedToken = DecimalMath.divCeil(_TOTAL_RAISED_FUNDS_, _FINAL_PRICE_);
|
||||||
IERC20(_TOKEN_ADDRESS_).safeTransfer(to, _TOTAL_TOKEN_AMOUNT_.sub(allocatedToken));
|
IERC20(_TOKEN_ADDRESS_).safeTransfer(to, _TOTAL_TOKEN_AMOUNT_.sub(allocatedToken));
|
||||||
_TOTAL_TOKEN_AMOUNT_ = allocatedToken;
|
_TOTAL_TOKEN_AMOUNT_ = allocatedToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function initializeLiquidity(uint256 initialTokenAmount, uint256 lpFeeRate, bool isOpenTWAP) external preventReentrant onlyOwner {
|
function initializeLiquidity(uint256 initialTokenAmount, uint256 lpFeeRate, bool isOpenTWAP) external preventReentrant onlyOwner {
|
||||||
require(isSettled(), "NOT_SETTLED");
|
require(isSettled(), "NOT_SETTLED");
|
||||||
_INITIAL_POOL_ = IDVMFactory(_POOL_FACTORY_).createDODOVendingMachine(
|
uint256 totalUsedRaiseFunds = DecimalMath.mulFloor(_TOTAL_RAISED_FUNDS_, _USED_FUND_RATIO_);
|
||||||
_TOKEN_ADDRESS_,
|
_initializeLiquidity(initialTokenAmount, totalUsedRaiseFunds, lpFeeRate, isOpenTWAP);
|
||||||
_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));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function claimToken(address to) external {
|
function claimToken(address to) external {
|
||||||
|
require(isSettled(), "NOT_SETTLED");
|
||||||
uint256 totalAllocation = getUserTokenAllocation(msg.sender);
|
uint256 totalAllocation = getUserTokenAllocation(msg.sender);
|
||||||
_claimToken(to, totalAllocation);
|
_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 ============
|
// ============ Timeline Control Functions ============
|
||||||
|
|
||||||
function isDepositOpen() public view returns (bool) {
|
function isDepositOpen() public view returns (bool) {
|
||||||
|
|||||||
@@ -14,8 +14,7 @@ import {DecimalMath} from "../../lib/DecimalMath.sol";
|
|||||||
import {IERC20} from "../../intf/IERC20.sol";
|
import {IERC20} from "../../intf/IERC20.sol";
|
||||||
import {SafeERC20} from "../../lib/SafeERC20.sol";
|
import {SafeERC20} from "../../lib/SafeERC20.sol";
|
||||||
import {Vesting} from "./Vesting.sol";
|
import {Vesting} from "./Vesting.sol";
|
||||||
import {IDVM} from "../../DODOVendingMachine/intf/IDVM.sol";
|
|
||||||
import {IDVMFactory} from "../../Factory/DVMFactory.sol";
|
|
||||||
|
|
||||||
contract InstantFunding is Vesting {
|
contract InstantFunding is Vesting {
|
||||||
using SafeMath for uint256;
|
using SafeMath for uint256;
|
||||||
@@ -198,25 +197,9 @@ contract InstantFunding is Vesting {
|
|||||||
_TOTAL_TOKEN_AMOUNT_ = _TOTAL_ALLOCATED_TOKEN_;
|
_TOTAL_TOKEN_AMOUNT_ = _TOTAL_ALLOCATED_TOKEN_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function initializeLiquidity(uint256 initialTokenAmount, uint256 lpFeeRate, bool isOpenTWAP) external preventReentrant onlyOwner {
|
function initializeLiquidity(uint256 initialTokenAmount, uint256 lpFeeRate, bool isOpenTWAP) external preventReentrant onlyOwner {
|
||||||
require(isFundingEnd(),"FUNDING_NOT_FINISHED");
|
require(isFundingEnd(),"FUNDING_NOT_FINISHED");
|
||||||
_INITIAL_POOL_ = IDVMFactory(_POOL_FACTORY_).createDODOVendingMachine(
|
_initializeLiquidity(initialTokenAmount, _TOTAL_RAISED_FUNDS_, lpFeeRate, isOpenTWAP);
|
||||||
_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));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function claimToken(address to) external {
|
function claimToken(address to) external {
|
||||||
@@ -224,6 +207,10 @@ contract InstantFunding is Vesting {
|
|||||||
_claimToken(to, totalAllocation);
|
_claimToken(to, totalAllocation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function claimFund(address to) external preventReentrant onlyOwner {
|
||||||
|
_claimFunds(to,_TOTAL_RAISED_FUNDS_);
|
||||||
|
}
|
||||||
|
|
||||||
// ============ Timeline Control Functions ============
|
// ============ Timeline Control Functions ============
|
||||||
|
|
||||||
function isDepositOpen() public view returns (bool) {
|
function isDepositOpen() public view returns (bool) {
|
||||||
|
|||||||
@@ -13,23 +13,13 @@ import {SafeMath} from "../../lib/SafeMath.sol";
|
|||||||
import {DecimalMath} from "../../lib/DecimalMath.sol";
|
import {DecimalMath} from "../../lib/DecimalMath.sol";
|
||||||
import {IERC20} from "../../intf/IERC20.sol";
|
import {IERC20} from "../../intf/IERC20.sol";
|
||||||
import {SafeERC20} from "../../lib/SafeERC20.sol";
|
import {SafeERC20} from "../../lib/SafeERC20.sol";
|
||||||
|
import {IDVM} from "../../DODOVendingMachine/intf/IDVM.sol";
|
||||||
|
import {IDVMFactory} from "../../Factory/DVMFactory.sol";
|
||||||
|
|
||||||
contract Vesting is Storage {
|
contract Vesting is Storage {
|
||||||
using SafeMath for uint256;
|
using SafeMath for uint256;
|
||||||
using SafeERC20 for IERC20;
|
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 {
|
function claimLp(address to) external preventReentrant onlyOwner {
|
||||||
require(_INITIAL_POOL_ != address(0), "LIQUIDITY_NOT_ESTABLISHED");
|
require(_INITIAL_POOL_ != address(0), "LIQUIDITY_NOT_ESTABLISHED");
|
||||||
uint256 remainingLp = DecimalMath.mulFloor(
|
uint256 remainingLp = DecimalMath.mulFloor(
|
||||||
@@ -38,11 +28,10 @@ contract Vesting is Storage {
|
|||||||
);
|
);
|
||||||
uint256 claimableLp = _TOTAL_LP_.sub(remainingLp).sub(_CLAIMED_LP_);
|
uint256 claimableLp = _TOTAL_LP_.sub(remainingLp).sub(_CLAIMED_LP_);
|
||||||
|
|
||||||
IERC20(_INITIAL_POOL_).safeTransfer(to, claimableLp);
|
|
||||||
_CLAIMED_LP_ = _CLAIMED_LP_.add(claimableLp);
|
_CLAIMED_LP_ = _CLAIMED_LP_.add(claimableLp);
|
||||||
|
IERC20(_INITIAL_POOL_).safeTransfer(to, claimableLp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//tokenType 0: BaseToken, 1: Fund, 2: LpToken
|
//tokenType 0: BaseToken, 1: Fund, 2: LpToken
|
||||||
function getRemainingRatio(uint256 timestamp, uint256 tokenType) public view returns (uint256) {
|
function getRemainingRatio(uint256 timestamp, uint256 tokenType) public view returns (uint256) {
|
||||||
uint256 vestingStart;
|
uint256 vestingStart;
|
||||||
@@ -78,7 +67,39 @@ contract Vesting is Storage {
|
|||||||
totalAllocation
|
totalAllocation
|
||||||
);
|
);
|
||||||
uint256 claimableTokenAmount = totalAllocation.sub(remainingToken).sub(_CLAIMED_TOKEN_[msg.sender]);
|
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);
|
_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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -75,11 +75,13 @@ contract DODOStarterFactory is InitializableOwnable {
|
|||||||
uint256[] memory timeLine,
|
uint256[] memory timeLine,
|
||||||
uint256[] memory valueList,
|
uint256[] memory valueList,
|
||||||
uint256 sellTokenAmount
|
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_);
|
newFairFundPool = ICloneFactory(_CLONE_FACTORY_).clone(_FAIR_FUND_TEMPLATE_);
|
||||||
|
|
||||||
IERC20(addressList[1]).transferFrom(msg.sender, newFairFundPool,sellTokenAmount);
|
IERC20(addressList[1]).transferFrom(msg.sender, newFairFundPool,sellTokenAmount);
|
||||||
|
(bool success, ) = newFairFundPool.call{value: msg.value}("");
|
||||||
|
require(success, "Settle fund Transfer failed");
|
||||||
|
|
||||||
IDODOStarter(newFairFundPool).init(
|
IDODOStarter(newFairFundPool).init(
|
||||||
addressList,
|
addressList,
|
||||||
timeLine,
|
timeLine,
|
||||||
|
|||||||
@@ -71,6 +71,7 @@ contract DODOStarterProxy is ReentrancyGuard {
|
|||||||
) internal {
|
) internal {
|
||||||
if (isETH) {
|
if (isETH) {
|
||||||
if (amount > 0) {
|
if (amount > 0) {
|
||||||
|
require(msg.value == amount, "ETH_VALUE_WRONG");
|
||||||
IWETH(_WETH_).deposit{value: amount}();
|
IWETH(_WETH_).deposit{value: amount}();
|
||||||
if (to != address(this)) SafeERC20.safeTransfer(IERC20(_WETH_), to, amount);
|
if (to != address(this)) SafeERC20.safeTransfer(IERC20(_WETH_), to, amount);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user