Files
dodo-contractV2/contracts/CallAuction/impl/CAVesting.sol
2020-12-08 19:52:32 +08:00

89 lines
2.8 KiB
Solidity

/*
Copyright 2020 DODO ZOO.
SPDX-License-Identifier: Apache-2.0
*/
pragma solidity 0.6.9;
pragma experimental ABIEncoderV2;
import {SafeMath} from "../../lib/SafeMath.sol";
import {DecimalMath} from "../../lib/DecimalMath.sol";
import {Ownable} from "../../lib/Ownable.sol";
import {SafeERC20} from "../../lib/SafeERC20.sol";
import {IERC20} from "../../intf/IERC20.sol";
import {CAFunding} from "./CAFunding.sol";
/**
* @title CAVesting
* @author DODO Breeder
*
* @notice Lock Token and release it linearly
*/
contract CAVesting is CAFunding {
using SafeMath for uint256;
using SafeERC20 for IERC20;
modifier afterSettlement() {
require(_SETTLED_, "NOT_SETTLED");
_;
}
// ============ Functions ============
function claimBase() external afterSettlement {
uint256 claimableToken = getClaimableBaseBalance(msg.sender);
_transferBaseOut(msg.sender, claimableToken);
_CLAIMED_BASE_[msg.sender] = _CLAIMED_BASE_[msg.sender].add(claimableToken);
}
function claimQuote() external afterSettlement {
require(!_QUOTE_CLAIMED_[msg.sender], "QUOTE_CLAIMED");
_QUOTE_CLAIMED_[msg.sender] = true;
_transferQuoteOut(msg.sender, getClaimableQuoteBalance(msg.sender));
}
// ============ View ============
function getOriginBaseBalance(address user) public view returns (uint256) {
return _TOTAL_SOLD_BASE_.mul(_QUOTE_SHARES_[user]).div(_TOTAL_QUOTE_SHARES_);
}
function getClaimedBaseBalance(address holder) public view returns (uint256) {
return _CLAIMED_BASE_[holder];
}
function getClaimableBaseBalance(address holder) public view returns (uint256) {
uint256 remainingToken = getRemainingBaseBalance(holder);
return getOriginBaseBalance(holder).sub(remainingToken).sub(_CLAIMED_BASE_[holder]);
}
function getRemainingBaseBalance(address holder) public view returns (uint256) {
uint256 remainingRatio = getRemainingBaseRatio(block.timestamp);
return DecimalMath.mulFloor(getOriginBaseBalance(holder), remainingRatio);
}
function getRemainingBaseRatio(uint256 timestamp) public view returns (uint256) {
if (timestamp < _START_VESTING_TIME_) {
return DecimalMath.ONE;
}
uint256 timePast = timestamp.sub(_START_VESTING_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;
}
}
function getClaimableQuoteBalance(address holder) public view returns (uint256) {
if (!_QUOTE_CLAIMED_[msg.sender]) {
return 0;
} else {
return _TOTAL_UNUSED_QUOTE_.mul(_QUOTE_SHARES_[holder]).div(_TOTAL_QUOTE_SHARES_);
}
}
}