Add LP Vesting to CP
This commit is contained in:
@@ -48,7 +48,7 @@ contract CP is CPVesting {
|
|||||||
0. phase bid starttime
|
0. phase bid starttime
|
||||||
1. phase bid duration
|
1. phase bid duration
|
||||||
2. phase calm duration
|
2. phase calm duration
|
||||||
3. freeze duration
|
3. vesting duration
|
||||||
*/
|
*/
|
||||||
|
|
||||||
require(timeLine.length == 4, "LIST_LENGTH_WRONG");
|
require(timeLine.length == 4, "LIST_LENGTH_WRONG");
|
||||||
@@ -57,7 +57,7 @@ contract CP is CPVesting {
|
|||||||
_PHASE_BID_ENDTIME_ = _PHASE_BID_STARTTIME_.add(timeLine[1]);
|
_PHASE_BID_ENDTIME_ = _PHASE_BID_STARTTIME_.add(timeLine[1]);
|
||||||
_PHASE_CALM_ENDTIME_ = _PHASE_BID_ENDTIME_.add(timeLine[2]);
|
_PHASE_CALM_ENDTIME_ = _PHASE_BID_ENDTIME_.add(timeLine[2]);
|
||||||
|
|
||||||
_FREEZE_DURATION_ = timeLine[3];
|
_VESTING_DURATION_ = timeLine[3];
|
||||||
|
|
||||||
require(block.timestamp <= _PHASE_BID_STARTTIME_, "TIMELINE_WRONG");
|
require(block.timestamp <= _PHASE_BID_STARTTIME_, "TIMELINE_WRONG");
|
||||||
|
|
||||||
@@ -67,6 +67,7 @@ contract CP is CPVesting {
|
|||||||
1. owner quote ratio
|
1. owner quote ratio
|
||||||
2. k
|
2. k
|
||||||
3. i
|
3. i
|
||||||
|
4. cliff rate
|
||||||
*/
|
*/
|
||||||
|
|
||||||
require(valueList.length == 4, "LIST_LENGTH_WRONG");
|
require(valueList.length == 4, "LIST_LENGTH_WRONG");
|
||||||
@@ -75,10 +76,12 @@ contract CP is CPVesting {
|
|||||||
_OWNER_QUOTE_RATIO_ = valueList[1];
|
_OWNER_QUOTE_RATIO_ = valueList[1];
|
||||||
_K_ = valueList[2];
|
_K_ = valueList[2];
|
||||||
_I_ = valueList[3];
|
_I_ = valueList[3];
|
||||||
|
_CLIFF_RATE_ = valueList[4];
|
||||||
|
|
||||||
require(_I_ > 0 && _I_ <= 10**36, "I_VALUE_WRONG");
|
require(_I_ > 0 && _I_ <= 1e36, "I_VALUE_WRONG");
|
||||||
require(_K_ <= 10**18, "K_VALUE_WRONG");
|
require(_K_ <= 1e18, "K_VALUE_WRONG");
|
||||||
require(_OWNER_QUOTE_RATIO_ <= 10**18, "OWNER_RATIO_WRONG");
|
require(_OWNER_QUOTE_RATIO_ <= 1e18, "OWNER_RATIO_WRONG");
|
||||||
|
require(_CLIFF_RATE_ <= 1e18, "CLIFF_RATE_WRONG");
|
||||||
|
|
||||||
_TOTAL_BASE_ = _BASE_TOKEN_.balanceOf(address(this));
|
_TOTAL_BASE_ = _BASE_TOKEN_.balanceOf(address(this));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ contract CPFunding is CPStorage {
|
|||||||
_UNUSED_QUOTE_ = _QUOTE_TOKEN_.balanceOf(address(this)).sub(poolQuote).sub(ownerQuote);
|
_UNUSED_QUOTE_ = _QUOTE_TOKEN_.balanceOf(address(this)).sub(poolQuote).sub(ownerQuote);
|
||||||
_UNUSED_BASE_ = _BASE_TOKEN_.balanceOf(address(this)).sub(poolBase);
|
_UNUSED_BASE_ = _BASE_TOKEN_.balanceOf(address(this)).sub(poolBase);
|
||||||
|
|
||||||
// 这里的目的是让开盘价尽量等于avgPrice
|
// 这里的目的是让midPrice尽量等于avgPrice
|
||||||
// 我们统一设定k=1,如果quote和base不平衡,就必然要截断一边
|
// 我们统一设定k=1,如果quote和base不平衡,就必然要截断一边
|
||||||
// DVM截断了quote,所以如果进入池子的quote很多,就要把quote设置成DVM的base
|
// DVM截断了quote,所以如果进入池子的quote很多,就要把quote设置成DVM的base
|
||||||
// m = avgPrice
|
// m = avgPrice
|
||||||
@@ -79,16 +79,16 @@ contract CPFunding is CPStorage {
|
|||||||
_poolQuoteToken = address(_QUOTE_TOKEN_);
|
_poolQuoteToken = address(_QUOTE_TOKEN_);
|
||||||
_poolI = 1;
|
_poolI = 1;
|
||||||
} else if (poolQuote < baseDepth) {
|
} else if (poolQuote < baseDepth) {
|
||||||
// poolI up round
|
// poolI round up
|
||||||
_poolBaseToken = address(_BASE_TOKEN_);
|
_poolBaseToken = address(_BASE_TOKEN_);
|
||||||
_poolQuoteToken = address(_QUOTE_TOKEN_);
|
_poolQuoteToken = address(_QUOTE_TOKEN_);
|
||||||
uint256 ratio = DecimalMath.ONE.sub(DecimalMath.divCeil(poolQuote, baseDepth));
|
uint256 ratio = DecimalMath.ONE.sub(DecimalMath.divFloor(poolQuote, baseDepth));
|
||||||
_poolI = avgPrice.mul(ratio).mul(ratio).divCeil(DecimalMath.ONE2);
|
_poolI = avgPrice.mul(ratio).mul(ratio).divCeil(DecimalMath.ONE2);
|
||||||
} else if (poolQuote > baseDepth) {
|
} else if (poolQuote > baseDepth) {
|
||||||
// poolI down round
|
// poolI round down
|
||||||
_poolBaseToken = address(_QUOTE_TOKEN_);
|
_poolBaseToken = address(_QUOTE_TOKEN_);
|
||||||
_poolQuoteToken = address(_BASE_TOKEN_);
|
_poolQuoteToken = address(_BASE_TOKEN_);
|
||||||
uint256 ratio = DecimalMath.ONE.sub(DecimalMath.divFloor(baseDepth, poolQuote));
|
uint256 ratio = DecimalMath.ONE.sub(DecimalMath.divCeil(baseDepth, poolQuote));
|
||||||
_poolI = DecimalMath.reciprocalFloor(avgPrice).mul(ratio).mul(ratio).div(
|
_poolI = DecimalMath.reciprocalFloor(avgPrice).mul(ratio).mul(ratio).div(
|
||||||
DecimalMath.ONE2
|
DecimalMath.ONE2
|
||||||
);
|
);
|
||||||
@@ -108,7 +108,7 @@ contract CPFunding is CPStorage {
|
|||||||
_transferQuoteOut(_POOL_, poolQuote);
|
_transferQuoteOut(_POOL_, poolQuote);
|
||||||
_transferQuoteOut(_OWNER_, ownerQuote);
|
_transferQuoteOut(_OWNER_, ownerQuote);
|
||||||
|
|
||||||
IDVM(_POOL_).buyShares(address(this));
|
_TOTAL_LP_AMOUNT_ = IDVM(_POOL_).buyShares(address(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
// in case something wrong with base token contract
|
// in case something wrong with base token contract
|
||||||
|
|||||||
@@ -26,7 +26,6 @@ contract CPStorage is InitializableOwnable, ReentrancyGuard {
|
|||||||
uint256 public _PHASE_BID_ENDTIME_;
|
uint256 public _PHASE_BID_ENDTIME_;
|
||||||
uint256 public _PHASE_CALM_ENDTIME_;
|
uint256 public _PHASE_CALM_ENDTIME_;
|
||||||
uint256 public _SETTLED_TIME_;
|
uint256 public _SETTLED_TIME_;
|
||||||
uint256 public _FREEZE_DURATION_;
|
|
||||||
bool public _SETTLED_;
|
bool public _SETTLED_;
|
||||||
|
|
||||||
// ============ Core Address ============
|
// ============ Core Address ============
|
||||||
@@ -50,8 +49,7 @@ contract CPStorage is InitializableOwnable, ReentrancyGuard {
|
|||||||
|
|
||||||
uint256 public _TOTAL_SHARES_;
|
uint256 public _TOTAL_SHARES_;
|
||||||
mapping(address => uint256) internal _SHARES_;
|
mapping(address => uint256) internal _SHARES_;
|
||||||
mapping(address => bool) internal _QUOTE_CLAIMED_;
|
mapping(address => bool) internal _CLAIMED_;
|
||||||
mapping(address => bool) internal _BASE_CLAIMED_;
|
|
||||||
|
|
||||||
address public _POOL_FACTORY_;
|
address public _POOL_FACTORY_;
|
||||||
address public _POOL_;
|
address public _POOL_;
|
||||||
@@ -68,6 +66,12 @@ contract CPStorage is InitializableOwnable, ReentrancyGuard {
|
|||||||
uint256 public _K_;
|
uint256 public _K_;
|
||||||
uint256 public _I_;
|
uint256 public _I_;
|
||||||
|
|
||||||
|
// ============ LP Token Vesting ============
|
||||||
|
|
||||||
|
uint256 public _TOTAL_LP_AMOUNT_;
|
||||||
|
uint256 public _VESTING_DURATION_;
|
||||||
|
uint256 public _CLIFF_RATE_;
|
||||||
|
|
||||||
// ============ Modifiers ============
|
// ============ Modifiers ============
|
||||||
|
|
||||||
modifier phaseBid() {
|
modifier phaseBid() {
|
||||||
|
|||||||
@@ -31,26 +31,37 @@ contract CPVesting is CPFunding {
|
|||||||
_;
|
_;
|
||||||
}
|
}
|
||||||
|
|
||||||
modifier afterFreeze() {
|
// ============ Bidder Functions ============
|
||||||
require(block.timestamp >= _SETTLED_TIME_.add(_FREEZE_DURATION_), "FREEZED");
|
|
||||||
_;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ============ Functions ============
|
function bidderClaim() external afterSettlement {
|
||||||
|
require(!_CLAIMED_[msg.sender], "ALREADY_CLAIMED");
|
||||||
|
_CLAIMED_[msg.sender] = true;
|
||||||
|
|
||||||
function claimBase() external afterSettlement {
|
|
||||||
require(!_BASE_CLAIMED_[msg.sender], "BASE_CLAIMED");
|
|
||||||
_BASE_CLAIMED_[msg.sender] = true;
|
|
||||||
_transferBaseOut(msg.sender, _UNUSED_BASE_.mul(_SHARES_[msg.sender]).div(_TOTAL_SHARES_));
|
_transferBaseOut(msg.sender, _UNUSED_BASE_.mul(_SHARES_[msg.sender]).div(_TOTAL_SHARES_));
|
||||||
}
|
|
||||||
|
|
||||||
function claimQuote() external afterSettlement {
|
|
||||||
require(!_QUOTE_CLAIMED_[msg.sender], "QUOTE_CLAIMED");
|
|
||||||
_QUOTE_CLAIMED_[msg.sender] = true;
|
|
||||||
_transferQuoteOut(msg.sender, _UNUSED_QUOTE_.mul(_SHARES_[msg.sender]).div(_TOTAL_SHARES_));
|
_transferQuoteOut(msg.sender, _UNUSED_QUOTE_.mul(_SHARES_[msg.sender]).div(_TOTAL_SHARES_));
|
||||||
}
|
}
|
||||||
|
|
||||||
function claimLPToken() external onlyOwner afterFreeze {
|
// ============ Owner Functions ============
|
||||||
IERC20(_POOL_).safeTransfer(_OWNER_, IERC20(_POOL_).balanceOf(address(this)));
|
|
||||||
|
function claimLPToken() external onlyOwner afterSettlement {
|
||||||
|
IERC20(_POOL_).safeTransfer(_OWNER_, getClaimableLPToken());
|
||||||
|
}
|
||||||
|
|
||||||
|
function getClaimableLPToken() public view afterSettlement returns (uint256) {
|
||||||
|
uint256 remainingLPToken = DecimalMath.mulFloor(
|
||||||
|
getRemainingLPRatio(block.timestamp),
|
||||||
|
_TOTAL_LP_AMOUNT_
|
||||||
|
);
|
||||||
|
return IERC20(_POOL_).balanceOf(address(this)).sub(remainingLPToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getRemainingLPRatio(uint256 timestamp) public view afterSettlement returns (uint256) {
|
||||||
|
uint256 timePast = timestamp.sub(_SETTLED_TIME_);
|
||||||
|
if (timePast < _VESTING_DURATION_) {
|
||||||
|
uint256 remainingTime = _VESTING_DURATION_.sub(timePast);
|
||||||
|
return DecimalMath.ONE.sub(_CLIFF_RATE_).mul(remainingTime).div(_VESTING_DURATION_);
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user