Files
dodo-contractV2/contracts/DODOToken/DODOCirculationHelper.sol

89 lines
2.9 KiB
Solidity
Raw Normal View History

2021-02-01 13:31:03 +08:00
/*
Copyright 2020 DODO ZOO.
SPDX-License-Identifier: Apache-2.0
*/
pragma solidity 0.6.9;
pragma experimental ABIEncoderV2;
import {IERC20} from "../intf/IERC20.sol";
import {SafeMath} from "../lib/SafeMath.sol";
import {DecimalMath} from "../lib/DecimalMath.sol";
2021-02-03 00:05:45 +08:00
import {InitializableOwnable} from "../lib/InitializableOwnable.sol";
2021-02-03 00:05:45 +08:00
contract DODOCirculationHelper is InitializableOwnable {
using SafeMath for uint256;
// ============ Storage ============
2021-02-03 00:05:45 +08:00
address immutable _VDODO_TOKEN_;
address immutable _DODO_TOKEN_;
address[] _LOCKED_CONTRACT_ADDRESS_;
2021-02-01 13:31:03 +08:00
uint256 public _MIN_PENALTY_RATIO_ = 5 * 10**16; // 5%
uint256 public _MAX_PENALTY_RATIO_ = 15 * 10**16; // 15%
2021-02-03 00:05:45 +08:00
constructor(address vDodoToken,address dodoToken) public {
_VDODO_TOKEN_ = vDodoToken;
2021-02-01 13:31:03 +08:00
_DODO_TOKEN_ = dodoToken;
2021-02-03 00:05:45 +08:00
}
2021-02-01 13:31:03 +08:00
2021-02-04 15:32:05 +08:00
function addLockedContractAddress(address lockedContract) external onlyOwner {
require(lockedContract != address(0));
_LOCKED_CONTRACT_ADDRESS_.push(lockedContract);
}
2021-02-01 13:31:03 +08:00
2021-02-04 15:32:05 +08:00
function removeLockedContractAddress(address lockedContract) external onlyOwner {
require(lockedContract != address(0));
address[] memory lockedContractAddress = _LOCKED_CONTRACT_ADDRESS_;
for (uint256 i = 0; i < lockedContractAddress.length; i++) {
if (lockedContractAddress[i] == lockedContract) {
lockedContractAddress[i] = lockedContractAddress[lockedContractAddress.length - 1];
break;
}
}
_LOCKED_CONTRACT_ADDRESS_ = lockedContractAddress;
_LOCKED_CONTRACT_ADDRESS_.pop();
}
2021-02-01 13:31:03 +08:00
function getCirculation() public view returns (uint256 circulation) {
2021-02-03 00:05:45 +08:00
circulation = 10**10 * 10**18;
2021-02-01 13:31:03 +08:00
for (uint256 i = 0; i < _LOCKED_CONTRACT_ADDRESS_.length; i++) {
circulation -= IERC20(_DODO_TOKEN_).balanceOf(_LOCKED_CONTRACT_ADDRESS_[i]);
}
}
2021-02-06 18:11:07 +08:00
function getDodoWithdrawFeeRatio() external view returns (uint256 ratio) {
2021-02-01 13:31:03 +08:00
uint256 dodoCirculationAmout = getCirculation();
uint256 x =
DecimalMath.divCeil(
dodoCirculationAmout,
2021-02-03 00:05:45 +08:00
IERC20(_VDODO_TOKEN_).totalSupply()
);
2021-02-03 15:28:49 +08:00
ratio = geRatioValue(x);
}
2021-02-03 18:56:01 +08:00
2021-02-03 15:28:49 +08:00
function geRatioValue(uint256 input) public view returns (uint256 ratio) {
2021-02-03 18:56:01 +08:00
// (x - 1)^2 / 81 + (y - 15)^2 / 100 = 1
// y = 5% (x ≤ 1)
// y = 15% (x ≥ 10)
// y = 15% - 10% * sqrt(1-[(x-1)/9]^2)
2021-02-03 15:28:49 +08:00
if (input <= 10**18) {
return _MIN_PENALTY_RATIO_;
2021-02-03 15:28:49 +08:00
} else if (input >= 10**19) {
return _MAX_PENALTY_RATIO_;
} else {
2021-02-03 15:28:49 +08:00
uint256 xTemp = input.sub(DecimalMath.ONE).div(9);
2021-02-01 13:31:03 +08:00
uint256 premium = DecimalMath.ONE2.sub(xTemp.mul(xTemp)).sqrt();
ratio =
_MAX_PENALTY_RATIO_ -
DecimalMath.mulFloor(_MAX_PENALTY_RATIO_ - _MIN_PENALTY_RATIO_, premium);
}
}
}