update vDODO

This commit is contained in:
owen05
2021-02-01 11:17:51 +08:00
parent eb0b6ca13d
commit c7e22612bc

View File

@@ -21,7 +21,7 @@ interface IGovernance {
interface IDODOLockedHelper { interface IDODOLockedHelper {
function getDodoLockedAmount() external returns (uint256); function getDodoLockedAmount() external view returns (uint256);
} }
@@ -123,7 +123,7 @@ contract vDODOToken is InitializableOwnable ,ReentrancyGuard{
} }
function changePerReward(uint256 _dodoPerBlock) public onlyOwner { function changePerReward(uint256 _dodoPerBlock) public onlyOwner {
_updateAlpha(); _updateAlpha(getAlpha());
dodoPerBlock = _dodoPerBlock; dodoPerBlock = _dodoPerBlock;
emit ChangePerReward(dodoPerBlock); emit ChangePerReward(dodoPerBlock);
} }
@@ -161,15 +161,15 @@ contract vDODOToken is InitializableOwnable ,ReentrancyGuard{
_dodoAmount _dodoAmount
); );
_updateAlpha(); uint tmpAlpha = getAlpha();
UserInfo storage user = userInfo[msg.sender]; UserInfo storage user = userInfo[msg.sender];
user.vdodoAmount = user.vdodoAmount.add(_dodoAmount.div(alpha)); user.vdodoAmount = user.vdodoAmount.add(_dodoAmount.div(tmpAlpha));
if(user.superior == address(0) && _superiorAddress != address(0) && _superiorAddress != msg.sender){ if(user.superior == address(0) && _superiorAddress != address(0) && _superiorAddress != msg.sender){
user.superior = _superiorAddress; user.superior = _superiorAddress;
} }
uint256 _dodoAmountDivAlpha = DecimalMath.divFloor(_dodoAmount, alpha); uint256 _dodoAmountDivAlpha = DecimalMath.divFloor(_dodoAmount, tmpAlpha);
if(user.superior != address(0)){ if(user.superior != address(0)){
UserInfo storage superiorUser = userInfo[user.superior]; UserInfo storage superiorUser = userInfo[user.superior];
@@ -183,6 +183,8 @@ contract vDODOToken is InitializableOwnable ,ReentrancyGuard{
totalSupply = totalSupply.add(_dodoAmountDivAlpha); totalSupply = totalSupply.add(_dodoAmountDivAlpha);
} }
_updateAlpha(tmpAlpha);
emit Deposit(msg.sender, _superiorAddress, _dodoAmount); emit Deposit(msg.sender, _superiorAddress, _dodoAmount);
} }
@@ -193,38 +195,30 @@ contract vDODOToken is InitializableOwnable ,ReentrancyGuard{
require(userAmount >= _vDodoAmount, "vDODOToken: no enough vdodo token"); require(userAmount >= _vDodoAmount, "vDODOToken: no enough vdodo token");
require(!user.hasParticipateGov, "vDODOToken: hasParticipateGov"); require(!user.hasParticipateGov, "vDODOToken: hasParticipateGov");
_updateAlpha(); uint256 tmpAlpha = getAlpha();
user.vdodoAmount = userAmount.sub(_vDodoAmount); user.vdodoAmount = userAmount.sub(_vDodoAmount);
if(user.superior != address(0)) { if(user.superior != address(0)) {
UserInfo storage superiorUser = userInfo[user.superior]; UserInfo storage superiorUser = userInfo[user.superior];
superiorUser.vdodoAmount = superiorUser.vdodoAmount.sub(_vDodoAmount.mul(_MAG_SP_AMOUNT_).div(100)); superiorUser.vdodoAmount = superiorUser.vdodoAmount.sub(_vDodoAmount.mul(_MAG_SP_AMOUNT_).div(100));
uint256 _overdraft = _vDodoAmount.mul(alpha).mul(_MAG_SP_AMOUNT_).div(100); uint256 _overdraft = _vDodoAmount.mul(tmpAlpha).mul(_MAG_SP_AMOUNT_).div(100);
superiorUser.overdraft = superiorUser.overdraft.sub(_overdraft); superiorUser.overdraft = superiorUser.overdraft.sub(_overdraft);
totalSupply = totalSupply.sub(_vDodoAmount.mul(_MAG_SP_AMOUNT_ + 100).div(100)); totalSupply = totalSupply.sub(_vDodoAmount.mul(_MAG_SP_AMOUNT_ + 100).div(100));
} else { } else {
totalSupply = totalSupply.sub(_vDodoAmount); totalSupply = totalSupply.sub(_vDodoAmount);
} }
(uint256 dodoReceive, uint256 destroyDodoAmount, uint256 withdrawFeeAmount) = getWithdrawAmount(_vDodoAmount);
uint256 feeRatio = _checkReward(); IERC20(_DODO_TOKEN_).transfer(msg.sender, dodoReceive);
_transfer(address(this), address(0), destroyDodoAmount);
uint256 withdrawDodoAmount = alpha.mul(_vDodoAmount); tmpAlpha = tmpAlpha.add(withdrawFeeAmount.div(totalSupply));
_updateAlpha(tmpAlpha);
uint256 withdrawFeeAmount = DecimalMath.mulCeil(withdrawDodoAmount,feeRatio).div(100);
uint256 dodoReceive = withdrawDodoAmount.sub(withdrawFeeAmount);
IERC20(_DODO_TOKEN_).transfer(msg.sender, dodoReceive);
if(dodoFeeDestroyRatio > 0){
uint256 destroyDodoAmount = DecimalMath.mulCeil(withdrawDodoAmount,dodoFeeDestroyRatio).div(100);
_transfer(address(this), address(0), destroyDodoAmount);
withdrawFeeAmount = withdrawFeeAmount.sub(destroyDodoAmount);
}
alpha = alpha.add(withdrawFeeAmount.div(totalSupply));
emit Withdraw(msg.sender, _vDodoAmount); emit Withdraw(msg.sender, _vDodoAmount);
} }
@@ -298,18 +292,41 @@ contract vDODOToken is InitializableOwnable ,ReentrancyGuard{
withDrawAmount = user.vdodoAmount.mul(alpha).sub(user.overdraft); withDrawAmount = user.vdodoAmount.mul(alpha).sub(user.overdraft);
} }
function getAlpha() public view returns (uint256) {
// ============ internal function ============
function _updateAlpha() internal {
uint256 accuDODO = dodoPerBlock * (block.number.sub(lastRewardBlock)); uint256 accuDODO = dodoPerBlock * (block.number.sub(lastRewardBlock));
if(totalSupply > 0){ if(totalSupply > 0){
alpha = alpha.add(accuDODO.div(totalSupply)); return alpha.add(accuDODO.div(totalSupply));
}else {
return alpha;
} }
}
function getWithdrawAmount(uint256 vDodoAmount) public view returns(uint256 dodoReceive, uint256 destroyDodoAmount, uint256 withdrawFeeAmount) {
uint256 feeRatio = _checkReward();
uint256 tmpAlpha = getAlpha();
uint256 withdrawDodoAmount = tmpAlpha.mul(vDodoAmount);
withdrawFeeAmount = DecimalMath.mulCeil(withdrawDodoAmount,feeRatio).div(100);
dodoReceive = withdrawDodoAmount.sub(withdrawFeeAmount);
if(dodoFeeDestroyRatio > 0){
destroyDodoAmount = DecimalMath.mulCeil(withdrawDodoAmount,dodoFeeDestroyRatio).div(100);
withdrawFeeAmount = withdrawFeeAmount.sub(destroyDodoAmount);
}else {
destroyDodoAmount = 0;
}
}
// ============ internal function ============
function _updateAlpha(uint256 newAlpha) internal {
alpha = newAlpha;
lastRewardBlock = block.number; lastRewardBlock = block.number;
} }
// ============= Helper and calculation function =============== // ============= Helper and calculation function ===============
function _checkReward() internal returns (uint256) { function _checkReward() internal view returns (uint256) {
uint256 dodoTotalLockedAmout = IDODOLockedHelper(_DODO_LOCKED_HELPER_).getDodoLockedAmount(); uint256 dodoTotalLockedAmout = IDODOLockedHelper(_DODO_LOCKED_HELPER_).getDodoLockedAmount();
// (x - 1)^2 / 81 + (y - 15)^2 / 100 = 1 ==> y = sqrt(100* (x*x +2x ) / 81)) +15 // (x - 1)^2 / 81 + (y - 15)^2 / 100 = 1 ==> y = sqrt(100* (x*x +2x ) / 81)) +15
// y = 5 (x ≤ 1) // y = 5 (x ≤ 1)