View Source: contracts/governance/Vesting/DevelopmentFund.sol
You can use this contract for timed token release from Dev Fund.
Enums
enum Status {
Deployed,
Active,
Expired
}
Constants & Variables
contract IERC20 public SOV;
enum DevelopmentFund.Status public status;
address public lockedTokenOwner;
address public unlockedTokenOwner;
address public safeVault;
address public newLockedTokenOwner;
uint256 public lastReleaseTime;
uint256[] public releaseDuration;
uint256[] public releaseTokenAmount;
Events
event DevelopmentFundActivated();
event DevelopmentFundExpired();
event NewLockedOwnerAdded(address indexed _initiator, address indexed _newLockedOwner);
event NewLockedOwnerApproved(address indexed _initiator, address indexed _oldLockedOwner, address indexed _newLockedOwner);
event UnlockedOwnerUpdated(address indexed _initiator, address indexed _newUnlockedOwner);
event TokenDeposit(address indexed _initiator, uint256 _amount);
event TokenReleaseChanged(address indexed _initiator, uint256 _releaseCount);
event LockedTokenTransferByUnlockedOwner(address indexed _initiator, address indexed _receiver, uint256 _amount);
event UnlockedTokenWithdrawalByUnlockedOwner(address indexed _initiator, uint256 _amount, uint256 _releaseCount);
event LockedTokenTransferByLockedOwner(address indexed _initiator, address indexed _receiver, uint256 _amount);
modifier onlyLockedTokenOwner() internal
modifier onlyUnlockedTokenOwner() internal
modifier checkStatus(enum DevelopmentFund.Status s) internal
Arguments
Name | Type | Description |
---|---|---|
s | enum DevelopmentFund.Status |
- constructor(address _SOV, address _lockedTokenOwner, address _safeVault, address _unlockedTokenOwner, uint256 _lastReleaseTime, uint256[] _releaseDuration, uint256[] _releaseTokenAmount)
- init()
- updateLockedTokenOwner(address _newLockedTokenOwner)
- approveLockedTokenOwner()
- updateUnlockedTokenOwner(address _newUnlockedTokenOwner)
- depositTokens(uint256 _amount)
- changeTokenReleaseSchedule(uint256 _newLastReleaseTime, uint256[] _releaseDuration, uint256[] _releaseTokenAmount)
- transferTokensByUnlockedTokenOwner()
- withdrawTokensByUnlockedTokenOwner(uint256 _amount)
- transferTokensByLockedTokenOwner(address _receiver)
- getReleaseDuration()
- getReleaseTokenAmount()
Setup the required parameters.
function (address _SOV, address _lockedTokenOwner, address _safeVault, address _unlockedTokenOwner, uint256 _lastReleaseTime, uint256[] _releaseDuration, uint256[] _releaseTokenAmount) public nonpayable
Arguments
Name | Type | Description |
---|---|---|
_SOV | address | The SOV token address. |
_lockedTokenOwner | address | The owner of the locked tokens & contract. |
_safeVault | address | The emergency wallet/contract to transfer token. |
_unlockedTokenOwner | address | The owner of the unlocked tokens. |
_lastReleaseTime | uint256 | If the last release time is to be changed, zero if no change required. |
_releaseDuration | uint256[] | The time duration between each release calculated from lastReleaseTime in seconds. |
_releaseTokenAmount | uint256[] | The amount of token to be released in each duration/interval. |
Source Code
constructor(
address _SOV,
address _lockedTokenOwner,
address _safeVault,
address _unlockedTokenOwner,
uint256 _lastReleaseTime,
uint256[] memory _releaseDuration,
uint256[] memory _releaseTokenAmount
) public {
require(_SOV != address(0), "Invalid SOV Address.");
require(_lockedTokenOwner != address(0), "Locked token & contract owner address invalid.");
require(_safeVault != address(0), "Safe Vault address invalid.");
require(_unlockedTokenOwner != address(0), "Unlocked token address invalid.");
SOV = IERC20(_SOV);
lockedTokenOwner = _lockedTokenOwner;
safeVault = _safeVault;
unlockedTokenOwner = _unlockedTokenOwner;
lastReleaseTime = _lastReleaseTime;
/// If last release time passed is zero, then current time stamp will be used as the last release time.
if (_lastReleaseTime == 0) {
lastReleaseTime = block.timestamp;
}
/// Checking if the schedule duration and token allocation length matches.
require(
_releaseDuration.length == _releaseTokenAmount.length,
"Release Schedule does not match."
);
/// Finally we update the token release schedule.
releaseDuration = _releaseDuration;
releaseTokenAmount = _releaseTokenAmount;
}
This function is called once after deployment for token transfer based on schedule.
function init() public nonpayable checkStatus
Source Code
function init() public checkStatus(Status.Deployed) {
uint256[] memory _releaseTokenAmount = releaseTokenAmount;
require(_releaseTokenAmount.length != 0, "Release Schedule not set.");
/// Getting the current release schedule total token amount.
uint256 _releaseTotalTokenAmount;
for (uint256 amountIndex = 0; amountIndex < _releaseTokenAmount.length; amountIndex++) {
_releaseTotalTokenAmount = _releaseTotalTokenAmount.add(
_releaseTokenAmount[amountIndex]
);
}
bool txStatus = SOV.transferFrom(msg.sender, address(this), _releaseTotalTokenAmount);
require(txStatus, "Not enough token sent to change release schedule.");
status = Status.Active;
emit DevelopmentFundActivated();
}
Update Locked Token Owner.
function updateLockedTokenOwner(address _newLockedTokenOwner) public nonpayable onlyLockedTokenOwner checkStatus
Arguments
Name | Type | Description |
---|---|---|
_newLockedTokenOwner | address | The owner of the locked tokens & contract. |
Source Code
function updateLockedTokenOwner(address _newLockedTokenOwner)
public
onlyLockedTokenOwner
checkStatus(Status.Active)
{
require(_newLockedTokenOwner != address(0), "New locked token owner address invalid.");
newLockedTokenOwner = _newLockedTokenOwner;
emit NewLockedOwnerAdded(msg.sender, _newLockedTokenOwner);
}
Approve Locked Token Owner.
function approveLockedTokenOwner() public nonpayable onlyUnlockedTokenOwner checkStatus
Source Code
function approveLockedTokenOwner() public onlyUnlockedTokenOwner checkStatus(Status.Active) {
require(newLockedTokenOwner != address(0), "No new locked owner added.");
emit NewLockedOwnerApproved(msg.sender, lockedTokenOwner, newLockedTokenOwner);
lockedTokenOwner = newLockedTokenOwner;
newLockedTokenOwner = address(0);
}
Update Unlocked Token Owner.
function updateUnlockedTokenOwner(address _newUnlockedTokenOwner) public nonpayable onlyLockedTokenOwner checkStatus
Arguments
Name | Type | Description |
---|---|---|
_newUnlockedTokenOwner | address | The new unlocked token owner. |
Source Code
function updateUnlockedTokenOwner(address _newUnlockedTokenOwner)
public
onlyLockedTokenOwner
checkStatus(Status.Active)
{
require(_newUnlockedTokenOwner != address(0), "New unlocked token owner address invalid.");
unlockedTokenOwner = _newUnlockedTokenOwner;
emit UnlockedOwnerUpdated(msg.sender, _newUnlockedTokenOwner);
}
Deposit tokens to this contract.
function depositTokens(uint256 _amount) public nonpayable checkStatus
Arguments
Name | Type | Description |
---|---|---|
_amount | uint256 | the amount of tokens deposited. |
Source Code
function depositTokens(uint256 _amount) public checkStatus(Status.Active) {
require(_amount > 0, "Amount needs to be bigger than zero.");
bool txStatus = SOV.transferFrom(msg.sender, address(this), _amount);
require(txStatus, "Token transfer was not successful.");
emit TokenDeposit(msg.sender, _amount);
}
Change the Token release schedule. It creates a completely new schedule, and does not append on the previous one.
function changeTokenReleaseSchedule(uint256 _newLastReleaseTime, uint256[] _releaseDuration, uint256[] _releaseTokenAmount) public nonpayable onlyLockedTokenOwner checkStatus
Arguments
Name | Type | Description |
---|---|---|
_newLastReleaseTime | uint256 | If the last release time is to be changed, zero if no change required. |
_releaseDuration | uint256[] | The time duration between each release calculated from lastReleaseTime in seconds. |
_releaseTokenAmount | uint256[] | The amount of token to be released in each duration/interval. |
Source Code
function changeTokenReleaseSchedule(
uint256 _newLastReleaseTime,
uint256[] memory _releaseDuration,
uint256[] memory _releaseTokenAmount
) public onlyLockedTokenOwner checkStatus(Status.Active) {
/// Checking if the schedule duration and token allocation length matches.
require(
_releaseDuration.length == _releaseTokenAmount.length,
"Release Schedule does not match."
);
/// If the last release time has to be changed, then you can pass a new one here.
/// Or else, the duration of release will be calculated based on this timestamp.
/// Even a future timestamp can be mentioned here.
if (_newLastReleaseTime != 0) {
lastReleaseTime = _newLastReleaseTime;
}
/// Checking if the contract have enough token balance for the release.
uint256 _releaseTotalTokenAmount;
for (uint256 amountIndex = 0; amountIndex < _releaseTokenAmount.length; amountIndex++) {
_releaseTotalTokenAmount = _releaseTotalTokenAmount.add(
_releaseTokenAmount[amountIndex]
);
}
/// Getting the current token balance of the contract.
uint256 remainingTokens = SOV.balanceOf(address(this));
/// If the token balance is not sufficient, then we transfer the change to contract.
if (remainingTokens < _releaseTotalTokenAmount) {
bool txStatus =
SOV.transferFrom(
msg.sender,
address(this),
_releaseTotalTokenAmount.sub(remainingTokens)
);
require(txStatus, "Not enough token sent to change release schedule.");
} else if (remainingTokens > _releaseTotalTokenAmount) {
/// If there are more tokens than required, send the extra tokens back.
bool txStatus =
SOV.transfer(msg.sender, remainingTokens.sub(_releaseTotalTokenAmount));
require(txStatus, "Token not received by the Locked Owner.");
}
/// Finally we update the token release schedule.
releaseDuration = _releaseDuration;
releaseTokenAmount = _releaseTokenAmount;
emit TokenReleaseChanged(msg.sender, _releaseDuration.length);
}
Transfers all of the remaining tokens in an emergency situation.
function transferTokensByUnlockedTokenOwner() public nonpayable onlyUnlockedTokenOwner checkStatus
Source Code
function transferTokensByUnlockedTokenOwner()
public
onlyUnlockedTokenOwner
checkStatus(Status.Active)
{
uint256 remainingTokens = SOV.balanceOf(address(this));
bool txStatus = SOV.transfer(safeVault, remainingTokens);
require(txStatus, "Token transfer was not successful. Check receiver address.");
status = Status.Expired;
emit LockedTokenTransferByUnlockedOwner(msg.sender, safeVault, remainingTokens);
emit DevelopmentFundExpired();
}
Withdraws all unlocked/released token.
function withdrawTokensByUnlockedTokenOwner(uint256 _amount) public nonpayable onlyUnlockedTokenOwner checkStatus
Arguments
Name | Type | Description |
---|---|---|
_amount | uint256 | The amount to be withdrawn. |
Source Code
function withdrawTokensByUnlockedTokenOwner(uint256 _amount)
public
onlyUnlockedTokenOwner
checkStatus(Status.Active)
{
require(_amount > 0, "Zero can't be withdrawn.");
uint256 count; /// To know how many elements to be removed from the release schedule.
uint256 amount = _amount; /// To know the total amount to be transferred.
uint256 newLastReleaseTimeMemory = lastReleaseTime; /// Better to use memory than storage.
uint256 releaseLength = releaseDuration.length.sub(1); /// Also checks if there are any elements in the release schedule.
/// Getting the amount of tokens, the number of releases and calculating the total duration.
while (
amount > 0 &&
newLastReleaseTimeMemory.add(releaseDuration[releaseLength]) < block.timestamp
) {
if (amount >= releaseTokenAmount[releaseLength]) {
amount = amount.sub(releaseTokenAmount[releaseLength]);
newLastReleaseTimeMemory = newLastReleaseTimeMemory.add(
releaseDuration[releaseLength]
);
count++;
} else {
/// This will be the last case, if correct amount is passed.
releaseTokenAmount[releaseLength] = releaseTokenAmount[releaseLength].sub(amount);
amount = 0;
}
releaseLength--;
}
/// Checking to see if atleast a single schedule was reached or not.
require(count > 0 || amount == 0, "No release schedule reached.");
/// If locked token owner tries to send a higher amount that schedule
uint256 value = _amount.sub(amount);
/// Now clearing up the release schedule.
releaseDuration.length -= count;
releaseTokenAmount.length -= count;
/// Updating the last release time.
lastReleaseTime = newLastReleaseTimeMemory;
/// Sending the amount to unlocked token owner.
bool txStatus = SOV.transfer(msg.sender, value);
require(txStatus, "Token transfer was not successful. Check receiver address.");
emit UnlockedTokenWithdrawalByUnlockedOwner(msg.sender, value, count);
}
Transfers all of the remaining tokens by the owner maybe for an upgrade.
function transferTokensByLockedTokenOwner(address _receiver) public nonpayable onlyLockedTokenOwner checkStatus
Arguments
Name | Type | Description |
---|---|---|
_receiver | address | The address which receives this token transfer. |
Source Code
function transferTokensByLockedTokenOwner(address _receiver)
public
onlyLockedTokenOwner
checkStatus(Status.Active)
{
uint256 remainingTokens = SOV.balanceOf(address(this));
bool txStatus = SOV.transfer(_receiver, remainingTokens);
require(txStatus, "Token transfer was not successful. Check receiver address.");
status = Status.Expired;
emit LockedTokenTransferByLockedOwner(msg.sender, _receiver, remainingTokens);
emit DevelopmentFundExpired();
}
Function to read the current token release duration.
function getReleaseDuration() public view
returns(_releaseTokenDuration uint256[])
Source Code
function getReleaseDuration() public view returns (uint256[] memory _releaseTokenDuration) {
return releaseDuration;
}
Function to read the current token release amount.
function getReleaseTokenAmount() public view
returns(_currentReleaseTokenAmount uint256[])
Source Code
function getReleaseTokenAmount()
public
view
returns (uint256[] memory _currentReleaseTokenAmount)
{
return releaseTokenAmount;
}
- Address
- Administered
- AdminRole
- AdvancedToken
- AdvancedTokenStorage
- Affiliates
- AffiliatesEvents
- ApprovalReceiver
- BProPriceFeed
- CheckpointsShared
- Constants
- Context
- DevelopmentFund
- DummyContract
- EnumerableAddressSet
- EnumerableBytes32Set
- EnumerableBytes4Set
- ERC20
- ERC20Detailed
- ErrorDecoder
- Escrow
- EscrowReward
- FeedsLike
- FeesEvents
- FeeSharingCollector
- FeeSharingCollectorProxy
- FeeSharingCollectorStorage
- FeesHelper
- FourYearVesting
- FourYearVestingFactory
- FourYearVestingLogic
- FourYearVestingStorage
- GenericTokenSender
- GovernorAlpha
- GovernorVault
- IApproveAndCall
- IChai
- IContractRegistry
- IConverterAMM
- IERC1820Registry
- IERC20_
- IERC20
- IERC777
- IERC777Recipient
- IERC777Sender
- IFeeSharingCollector
- IFourYearVesting
- IFourYearVestingFactory
- IFunctionsList
- ILiquidityMining
- ILiquidityPoolV1Converter
- ILoanPool
- ILoanToken
- ILoanTokenLogicBeacon
- ILoanTokenLogicModules
- ILoanTokenLogicProxy
- ILoanTokenModules
- ILoanTokenWRBTC
- ILockedSOV
- IMoCState
- IModulesProxyRegistry
- Initializable
- InterestUser
- IPot
- IPriceFeeds
- IPriceFeedsExt
- IProtocol
- IRSKOracle
- ISovryn
- ISovrynSwapNetwork
- IStaking
- ISwapsImpl
- ITeamVesting
- ITimelock
- IV1PoolOracle
- IVesting
- IVestingFactory
- IVestingRegistry
- IWrbtc
- IWrbtcERC20
- LenderInterestStruct
- LiquidationHelper
- LiquidityMining
- LiquidityMiningConfigToken
- LiquidityMiningProxy
- LiquidityMiningStorage
- LoanClosingsEvents
- LoanClosingsLiquidation
- LoanClosingsRollover
- LoanClosingsShared
- LoanClosingsWith
- LoanClosingsWithoutInvariantCheck
- LoanInterestStruct
- LoanMaintenance
- LoanMaintenanceEvents
- LoanOpenings
- LoanOpeningsEvents
- LoanParamsStruct
- LoanSettings
- LoanSettingsEvents
- LoanStruct
- LoanToken
- LoanTokenBase
- LoanTokenLogicBeacon
- LoanTokenLogicLM
- LoanTokenLogicProxy
- LoanTokenLogicStandard
- LoanTokenLogicStorage
- LoanTokenLogicWrbtc
- LoanTokenSettingsLowerAdmin
- LockedSOV
- MarginTradeStructHelpers
- Medianizer
- ModuleCommonFunctionalities
- ModulesCommonEvents
- ModulesProxy
- ModulesProxyRegistry
- MultiSigKeyHolders
- MultiSigWallet
- Mutex
- Objects
- OrderStruct
- OrigingVestingCreator
- OriginInvestorsClaim
- Ownable
- Pausable
- PausableOz
- PreviousLoanToken
- PreviousLoanTokenSettingsLowerAdmin
- PriceFeedRSKOracle
- PriceFeeds
- PriceFeedsLocal
- PriceFeedsMoC
- PriceFeedV1PoolOracle
- ProtocolAffiliatesInterface
- ProtocolLike
- ProtocolSettings
- ProtocolSettingsEvents
- ProtocolSettingsLike
- ProtocolSwapExternalInterface
- ProtocolTokenUser
- Proxy
- ProxyOwnable
- ReentrancyGuard
- RewardHelper
- RSKAddrValidator
- SafeERC20
- SafeMath
- SafeMath96
- setGet
- SharedReentrancyGuard
- SignedSafeMath
- SOV
- sovrynProtocol
- StakingAdminModule
- StakingGovernanceModule
- StakingInterface
- StakingProxy
- StakingRewards
- StakingRewardsProxy
- StakingRewardsStorage
- StakingShared
- StakingStakeModule
- StakingStorageModule
- StakingStorageShared
- StakingVestingModule
- StakingWithdrawModule
- State
- SwapsEvents
- SwapsExternal
- SwapsImplLocal
- SwapsImplSovrynSwap
- SwapsUser
- TeamVesting
- Timelock
- TimelockHarness
- TimelockInterface
- TokenSender
- UpgradableProxy
- USDTPriceFeed
- Utils
- VaultController
- Vesting
- VestingCreator
- VestingFactory
- VestingLogic
- VestingRegistry
- VestingRegistry2
- VestingRegistry3
- VestingRegistryLogic
- VestingRegistryProxy
- VestingRegistryStorage
- VestingStorage
- WeightedStakingModule
- WRBTC